|
| HOMEPAGE | INDICE FORUM | REGOLAMENTO | ::. | NEI PREFERITI | .:: | RSS Forum | RSS News | NEWS web | NEWS software | |
| PUBBLICITA' | | | ARTICOLI | WIN XP | VISTA | WIN 7 | REGISTRI | SOFTWARE | MANUALI | RECENSIONI | LINUX | HUMOR | HARDWARE | DOWNLOAD | | | CERCA nel FORUM » | |
25-08-2004, 03.02.15 | #1 |
Newbie
Registrato: 08-07-2004
Messaggi: 47
|
[C]NamedPipes
Se avvio un solo server e molti client nessun problema,il server è in grado di ricevere i dati da tutti i client,se però contemporaneamente avvio un'altro server,questo non è recettivo,cioè i dati inviati dai client vengono ricevuti solo dal primo server e da lui no,mentre io vorrei che i dati inviati da qualiasi client arrivassero a tutti i server attualmente attivi,non solo ad uno.Un pò di codice così si capisce meglio: server: Codice:
main() { DWORD dwThreadID; BOOL bConnected; HANDLE hPipe,hThread; while(1) { hPipe = CreateNamedPipe (PIPENAME,PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT,PIPE_UNLIMITED_INSTANCES, 0, 0, PIPETIMEOUT, NULL); if(hPipe == INVALID_HANDLE_VALUE) return -1; bConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); if(bConnected) { hThread = CreateThread(NULL,0,ListenerProc,hPipe,0 ,&dwThreadID); if(!hThread) return -1; else CloseHandle(hThread); } else CloseHandle(hPipe); } return 1; } DWORD WINAPI ListenerProc(LPVOID hPipe) { DWORD dwBytesRead = 0; char buff[512]; HANDLE hThisPipe = (HANDLE)hPipe; while (ReadFile(hThisPipe, buff, 512, &dwBytesRead, NULL)) { buff[dwBytesRead] = 0; //processa i dati letti //....... } FlushFileBuffers(hThisPipe); DisconnectNamedPipe(hThisPipe); CloseHandle(hThisPipe); return 1; } client: Codice:
BOOL Connect() { m_hPipe = CreateFile(PIPENAME, GENERIC_WRITE , 0, NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL); if(m_hPipe != INVALID_HANDLE_VALUE) return TRUE; return FALSE; } BOOL SendData(LPCSTR szData) { //....... DWORD dwBytesWritten; if(WriteFile(m_hPipe, szData, (DWORD)strlen(szData), &dwBytesWritten, NULL) != FALSE && dwBytesWritten == (DWORD)strlen(szData)) return TRUE; CloseHandle(m_hPipe); //............. return FALSE; } Nel server quando avvio due istanze del server CreateNamedPipe ritorna lo stesso valore numerico di hPipe per entrambe però solo la prima istanza salta la successiva ConnectNamedPipe(hPipe, NULL) quando arriva una connessione da un client ,l'altra si blocca li (e credo sia perchè l'handle è lo stesso ed è già impegnato) ma allora perchè GetLastError() non mi da nessun errore. Insomma voglio ottenere o di poter inviare da un client a tutti i server attivi oppure di avvisare l'utente che non è possibile aprire due server con la stessa pipe,cosa che non riesco a fare. Il tutto sotto windows (xp)
___________________________________
Sai che la fortuna è una religione:tu ci credi oppure no. |
25-08-2004, 10.05.18 | #2 |
Gold Member
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
|
Il "problema" è che l'API "CreateNamedPipe" può essere usata sia per creare una nuova istanza della pipe con gli attributi specificati (come nel tuo caso) e sia per reinstanziare una pipe già esistente, con gli stessi attributi o con nuovi attributi...
Nel tuo caso, lanciando più volte il server, non fai che reinstanziare la pipe creata dal primo server che lanci e che va a buon fine, tale pipe però è occupata già dal primo processo ed avendo lo stesso handle (dato che l'istanza della pipe è sempre una) ma accesso esclusiveo, tu non riesci ad usarla e tutti i processi server successivi rimangono inesorabilmente bloccati quando tentano di fare operazioni sulla pipe... GetLastError non restituisce errori. La soluzione più semplice che mi viene in mente (tenendo conto che è mattina ) è quella di modificare il server in modo che la sua prima istruzione sia quella di connettersi alla pipe... Connettendoti alla pipe riceverai un errore se la pipe non esiste (quindi sarai sicuro che non esistono altri processi server) e potrai così crearla, oppure ti connetterai con successo alla pipe creata o reinstanziata da un altro o più processi server ed in questo caso fermerai l'esecuzione avvisando l'utente che un processo server è già stato lanciato... Bye |
25-08-2004, 19.16.13 | #3 |
Newbie
Registrato: 08-07-2004
Messaggi: 47
|
Ok ho capito ci provo,grazie.
___________________________________
Sai che la fortuna è una religione:tu ci credi oppure no. |
25-08-2004, 20.59.08 | #4 | |
Newbie
Registrato: 08-07-2004
Messaggi: 47
|
Quota:
Una cosa che non mi è chiara è perchè ai thread figli di uno stesso server CreateNamedPipe assegna Handle diversi alla pipe,mentre se avvio un'altro server l'handle ritornato è lo stesso?In pratica più server ricevono la stessa istanza della pipe mentre in teoria non dovrebbe essere così.Se la funzione non si comportasse così di fatto non avrei problemi,cioè se si comportasse con i processi pari allo stesso modo in cui si comporta con i thread di uno stesso server.
___________________________________
Sai che la fortuna è una religione:tu ci credi oppure no. |
|
25-08-2004, 22.15.50 | #5 |
Newbie
Registrato: 08-07-2004
Messaggi: 47
|
Come non detto,ho risolto il problema con una createfile prima della createnamedpipe:
Codice:
hPipe = CreateFile(PIPENAME, GENERIC_WRITE , 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hPipe == INVALID_HANDLE_VALUE) hPipe = CreateNamedPipe(PIPENAME,PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, PIPETIMEOUT, NULL); else { CloseHandle(hPipe); return -1; } if(hPipe == INVALID_HANDLE_VALUE) return -1; Ora nella documentazione msdn ho letto che bisogna usare GetExitCodeThread() e infatti l'ho usata in questo modo: Codice:
if (GetExitCodeThread(m_hThread,&dwExitCode)) { if (dwExitCode != STILL_ACTIVE && dwExitCode < 0 ) return FALSE; } return TRUE;
___________________________________
Sai che la fortuna è una religione:tu ci credi oppure no. |
27-08-2004, 18.10.44 | #6 |
Newbie
Registrato: 08-07-2004
Messaggi: 47
|
Ho scoperto che 259 in realtà è il valore numerico di STILL_ACTIVE,questo significa che quando io vado a richiedere l'exit code del processo questo non è ancora terminato e invece dovrebbe dato che la funzione di callback è uscita quasi immediatamente con return -1.Anche mettendo quest'ultima istruzione come l'unica della callback (come prova) non cambiano le cose,il processo risulta comunque attivo.
___________________________________
Sai che la fortuna è una religione:tu ci credi oppure no. |
Utenti attualmente attivi che stanno leggendo questa discussione: 1 (0 utenti e 1 ospiti) | |
Strumenti discussione | |
|
|