2009-03-26 4 views

Antwort

11

wenn Sie recv rufen im Modus blockiert und es kehrt mit 0 Byte zu lesen, die Buchse getrennt hat, sonst es warten Bytes empfangen werden.

Schauen Sie in diesem FAQ 2.12

Beispiel von den auserwählten auf this Seite.

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

Ist nicht "Beej's Network Programming Guide" für Linux-Sockets? – AntonioCS

+0

BSD-Buchsen, und sie werden überall verwendet. –

4

Sie können nur feststellen, ob ein TCP-Socket "getrennt" ist, indem Sie versuchen, Daten zu senden. Dies liegt daran, dass das Protokoll so konzipiert ist, dass temporäre Ausfälle zwischen Peers möglich sind. Also, wenn Sie von A über R1 über R2 über R3 mit B verbinden und Daten für eine Weile senden und dann aufhören zu senden, könnten Sie R2-> R3 (zum Beispiel) trennen und weder A noch B würden bemerken (oder kümmern). Wenn Sie dann R2-> R4 und R4-> R3 angeschlossen haben und dann versucht haben, Daten zwischen A und B zu senden, dann würden die Dinge 'einfach funktionieren' und Sie würden es nie erfahren. Wenn Sie jedoch versucht haben, Daten zu senden, wenn R2-> R3 getrennt wurde, erhalten Sie (eventuell nach allen Wiederholungen der TCP-Ebene) einen Fehler zurück.

Nun können einige Betriebssysteme Sie möglicherweise darauf aufmerksam machen, dass Ihr lokaler Netzwerkadapter momentan nicht verbunden ist und Sie könnten damit sagen: "Ich bin nicht mehr mit meinen Kollegen verbunden", aber ich würde nicht t rate es.

Wenn Ihre Kollegen wissen, wann Verbindungen unterbrochen sind, dann verwenden Sie entweder eine Ping-Nachricht auf Anwendungsebene, um gelegentlich Daten zwischen den Peers zu senden, oder verwenden Sie TCP keep-alive. Persönlich würde ich für die Ping-Nachrichten gehen ...

Edit: Natürlich alles, was davon ausgeht, dass Sie wissen wollen, ob Sie noch Daten über eine Verbindung senden können, schließlich sind Sie TOLD, wenn die Client sendet nicht mehr, weil Ihre Lesevorgänge 0 Byte zurückgeben und Sie WISSEN, wenn die Sendeseite getrennt wird, weil Ihre Schreibvorgänge fehlschlagen; Sie wissen auch, wenn Sie Herunterfahren entweder die Sende- oder recv Seite Ihres eigenen Endes der Verbindung ...

Ich glaube, ich mit anfänglicher Darmreaktion Reaktion von „definieren getrennt“ stecken soll;)

2

Es gibt ein paar verschiedene Möglichkeiten, aber die häufigste ist das Ergebnis eines Sende zu überprüfen oder den Befehl erhalten:

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

Weitere Beispiele (komplett mit Fehlerprüfung, Client und Server) hier:

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

0

Wenn das Ergebnis von send() oder recv() SOCKET_ERROR ist und WSAGetLastError() WSAECONNRESET zurückgibt, hat der Client die Verbindung getrennt.
Von MSDN:

WSAECONNRESET

Verbindung von Peer zurückgesetzt.

Eine bestehende Verbindung wurde vom Remote-Host zwangsweise geschlossen.Diese führt normalerweise, wenn die Peer-Anwendung auf dem Remote-Host plötzlich gestoppt wird, der Host neu gestartet wird, das Host oder Remote-Netzwerk Schnittstelle deaktiviert ist, oder der Remote-Host verwendet eine harte schließen (siehe setsockopt für weitere Informationen über die SO_LINGER Option auf der Fernbedienung Buchse). Dieser Fehler kann auch dann auftreten, wenn eine Verbindung unterbrochen wurde, weil die Keep-Alive-Aktivität einen Fehler erkennt, während eine oder mehrere Operationen ausgeführt werden. Vorgänge, die gerade ausgeführt wurden, schlagen mit WSAENETRESET fehl. Nachfolgende Operationen schlagen mit WSAECONNRESET fehl.

Dies funktioniert auch mit nicht blockierenden Sockeln.

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