Come posso controllare se un cliente disconnesso attraverso Winsock in C ++?

StackOverflow https://stackoverflow.com/questions/685951

  •  22-08-2019
  •  | 
  •  

Domanda

Come posso controllare se un cliente scollegato attraverso Winsock in C ++?

È stato utile?

Soluzione

di Beej Programming Guide della rete

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 su questa 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
    }
}

Altri suggerimenti

Si può dire solo se un socket TCP è 'scollegato' tentando di inviare i dati. Questo perché la progettazione del protocollo è tale che si suppone per consentire interruzioni temporanee tra coetanei. Quindi, se ci si connette da A via via R1 R2 R3 via a B e inviare i dati per un po 'e poi interrompere l'invio si potrebbe staccare R2-> R3 (per esempio) e né A né B sarebbero accorti (o cura). Se poi collegato R2-> R4 e R4-> R3 e poi ha tentato di inviare i dati tra A e B, allora le cose sarebbero 'solo di lavoro' e che non avevo mai sapere. Se, tuttavia, si è tentato di inviare i dati quando R2-> R3 è stato scollegato allora si sarebbe (finalmente, dopo tutti i tentativi di livello TCP) ottiene un errore di nuovo.

Ora, alcuni sistemi operativi possono essere in grado di avvisare l'utente del fatto che la scheda di rete locale non è attualmente connesso e si potrebbe usare quella di dire "Non sono più collegato al mio pari", ma non vorrei consigliarlo.

Se avere i vostri coetanei sanno quando le connessioni vengono 'rotti' importante quindi utilizzare un messaggio di livello di applicazione 'ping' per inviare di tanto in tanto dei dati tra i peer o utilizzare il protocollo TCP keep-alive. Personalmente mi piacerebbe andare per i messaggi ping ...

Modifica 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 client non è più sta inviando perché il vostro letture tornerà 0 byte e non si sa quando si disconnette il suo lato di invio perché i vostri scrive fallirà; Sapete anche quando si spegne il PC sia sul lato di invio o RECV della propria estremità della connessione ...

Credo che avrei dovuto bloccato con risposta reazione istintiva iniziale di "definire disconnesso";)

Ci sono alcuni modi diversi, ma il più comune è quello di verificare il risultato di una trasmissione o comando di ricezione:

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

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

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

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

  

WSAECONNRESET

     

Connection reset by peer.

     

Una connessione esistente veniva chiusa forzatamente dall'host remoto. Questo   normalmente i risultati se l'applicazione pari sull'host remoto è   improvvisamente fermato, l'host viene riavviato, l'host o rete remota   interfaccia è bloccata, o l'host remoto utilizza un disco di chiusura (vedi   setsockopt per ulteriori informazioni sull'opzione SO_LINGER sul telecomando   socket). Questo errore può inoltre verificarsi se una connessione è stata interrotta a causa di   keep-alive attività rilevare un errore durante una o più operazioni   sono in corso. Le operazioni che erano in corso non riescono con   WSAENETRESET. Le operazioni successive non riescono con WSAECONNRESET.

Questo funziona anche con i socket non bloccanti.

int r = recv(sock, NULL, 0, 0);
if(r == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET){
    //client has disconnected!
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top