2009-03-26 18 views

risposta

11

se si chiama recv in modalità di blocco e ritorna con 0 byte leggono, il socket è disconnesso, altrimenti attendere per i byte da ricevere.

Look in questo FAQ 2.12

esempio da selezionare sulla this pagina.

int nRet; 

if((nRet = select(0, &fdread, NULL, NULL, NULL)) == SOCKET_ERROR) 
{ 
    // Error condition 
    // Check WSAGetLastError 
} 

if(nRet > 0) 
{ 
    // select() will return value 1 because i m using only one socket 
    // At this point, it should be checked whether the 
    // socket is part of a set. 

    if(FD_ISSET(s, &fdread)) 
    { 
     // A read event has occurred on socket s 
    } 
} 
+0

Non è la "Guida alla programmazione di rete di Beej" per i socket Linux? – AntonioCS

+0

socket BSD, e sono usati ovunque. –

4

Si può solo dire se un socket TCP è "disconnesso" tentando di inviare dati. Questo perché il design del protocollo è tale che dovrebbe consentire interruzioni temporanee tra pari. Quindi, se ci si collega da A a R1 tramite R2 tramite R3 a B e si inviano dati per un po 'e poi si interrompe l'invio, è possibile scollegare R2-> R3 (ad esempio) e né A né B noterebbero (o si preoccuperanno). Se hai quindi collegato R2-> R4 e R4-> R3 e poi hai provato a inviare dati tra A e B, le cose sarebbero "funzionanti" e non lo sapresti mai. Se, tuttavia, si è tentato di inviare dati quando R2-> R3 è stato disconnesso, si otterrebbe (eventualmente, dopo tutti i tentativi del livello TCP) un errore.

Ora, alcuni sistemi operativi potrebbero essere in grado di avvisare del fatto che la scheda di rete locale non è attualmente collegata e si potrebbe usare per dire "Non sono più connesso ai miei coetanei" ma non lo farei lo consiglio

Se i tuoi colleghi sanno quando le connessioni sono "interrotte" è importante quindi utilizzare un messaggio di "ping" a livello di applicazione per inviare occasionalmente i dati tra i peer o utilizzare TCP keep-alive. Personalmente mi piacerebbe andare per i messaggi ping ...

Edit: Naturalmente tutto ciò che è supponendo che si desidera sapere se è ancora possibile inviare i dati su una connessione, dopo tutto, ti si dice, quando il il client non invia più perché le tue letture restituiranno 0 byte e SAPPIA quando disconnette il suo lato di invio perché le tue scritture falliranno; Sapete anche quando si spegne il PC sia sul lato di invio o RECV della propria estremità della connessione ...

Credo Mi hanno bloccato con la risposta reazione istintiva iniziale di "definire disconnesso";)

2

Ci sono un paio di modi diversi, ma il più comune è quello di verificare il risultato di un invio o ricezione dei comandi:

nReadBytes = recv(sd, ReadBuffer, BufferSize, 0); 
if (nReadBytes == SOCKET_ERROR) 
{ 
    //error 
} 
nSendBytes = send(sd, WriteBuffer, BufferSize, 0); 
if (nSendBytes == SOCKET_ERROR) 
{ 
    //error 
} 

più esempi (completo di controllo degli errori, sia client che server) qui:

http://tangentsoft.net/wskfaq/examples/basics/

0

Se il risultato di send() o recv() è SOCKET_ERROR e WSAGetLastError() restituisce WSAECONNRESET il client si è disconnesso.
Da MSDN:

WSAECONNRESET

Connessione ripristinata dal peer.

Una connessione esistente è stata forzatamente chiusa dall'host remoto.Questo normalmente si verifica se l'host remoto è improvvisamente arrestato, l'host viene riavviato, l'interfaccia host o rete remota è disabilitata oppure l'host remoto utilizza una chiusura hardware (vedere setockopt per ulteriori informazioni su SO_LINGER opzione sul socket remoto). Questo errore può anche verificarsi se una connessione è stata interrotta a causa dell'attività di keep-alive che rileva un errore mentre una o più operazioni sono in corso. Operazioni in corso non riuscite con WSAENETRESET. Le operazioni successive non riescono con WSAECONNRESET.

Questo funziona anche con prese non bloccanti.

int r = recv(sock, NULL, 0, 0); 
if(r == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET){ 
    //client has disconnected! 
} 
Problemi correlati