tcp socket verbunden?
-
keine ahnung ob es in diesem fall unterschiede zw win und linux gibt deshalb im linux forum
wie kann man serverseitig prüfen ob der client noch mit dem socket (tcp)verbunden ist? (wird nur zum senden an den client verwendet)
kann man das nur feststellen wen send() nen fehler bringt?
-
Du kannst periodisch mit select() pruefen, ob der Socket noch beschreibbar ist. Ausserdem kannst Du mit select() pruefen, ob der Socket im Ausnahmezustand (exception state) ist.
-
beschreibbar ist der socket dann, wenn
der sende-puffer weitere bytes aufnehmen kann.
das heisst aber nicht, das der socket auf der
anderen seite bereit zum empfangen ist.pruefen, ob ein client noch verbunden ist kannst
du nur durch pollen, z.b. durch senden eines bytes
und erwarten einer antwort.
-
Wenn die Verbindung geschlossen wurde, ist auch der Sendepuffer nicht mehr da.
-
ja. wenn der client die verbindung aber nicht schliesst?
z.b. wenn er abstuerzt oder aehnliches?
-
entelechie schrieb:
ja. wenn der client die verbindung aber nicht schliesst?
z.b. wenn er abstuerzt oder aehnliches?Wenn der Client abstuerzt, wird sein Prozess beendet, und damit werden auch alle Handles geschlossen und deshalb alle TCP/IP-Verbindungen, die er offenhatte, getrennt.
-
Power Off schrieb:
entelechie schrieb:
ja. wenn der client die verbindung aber nicht schliesst?
z.b. wenn er abstuerzt oder aehnliches?Wenn der Client abstuerzt, wird sein Prozess beendet, und damit werden auch alle Handles geschlossen und deshalb alle TCP/IP-Verbindungen, die er offenhatte, getrennt.
Das fordert doch die Frage heraus. Was passiert dann wenn der ganze Rechner abstürzt, so dass er die Verbindung nicht von sich aus trennen kann? Oder was passiert wenn das Netz irgendwo zwischen Client und Server irreparabel getrennt ist?
-
Ponto schrieb:
Das fordert doch die Frage heraus. Was passiert dann wenn der ganze Rechner abstürzt, so dass er die Verbindung nicht von sich aus trennen kann?
Kommt drauf an, was Du unter "Absturz des Rechners" verstehst.
Wenn der Strom weg ist, also wenn die Netzwerkkarte keinen Saft mehr hat, ist der Fall klar: Die Gegenseite bekommt erst dann etwas mit, wenn sie versucht, zu senden. Da TCP/IP aber nach dem OSI-7-Schichten-Modell aufgebaut ist, sollte der Verlust des Transport-Layers eigentlich schon vorher bemerkt werden.
Haengt sich der Rechner bloss auf, wird erst nach einer Timeout-Zeit im TCP/IP-Stack bemerkt, dass die Verbindung nicht mehr steht.
Ich kenne das TCP/IP-Protokoll nicht gut genug, um sagen zu koennen, ob z.B. der Empfang eines Pakets bestaetigt wird, oder ob es eine Keep-Alive-Sequenz gibt, die prueft, ob der Empfaenger noch vorhanden ist.
Normalerweise muss sich eine Anwendung nicht darum kuemmern.
Ggf. muss man im Protokoll ueber dem TCP/IP-Protokoll, also im eigenen Protokoll, gelegentlich ein Pruef-Handshake implementieren, falls haeufige Ausfaelle ein Problem sind.
Meiner Erfahrung nach kann man sich aber voll und ganz auf die Error-Codes und die select()-States verlassen.
Ponto schrieb:
Oder was passiert wenn das Netz irgendwo zwischen Client und Server irreparabel getrennt ist?
siehe oben. Im Prinzip muesste der Verlust bemerkt werden, mindestens nach einer Timeout-Periode.
GNU/Linux ist da wesentlich besser als z.B. Windows. Verbindungsaufbau und -Trennung geht schneller, und viele Zustaende werden sofort bemerkt.
Hier etwas Lesestoff fuer die Neugierigen:
IP Protokoll: ftp://ftp.rfc-editor.org/in-notes/rfc791.txt (RFC 791)
TCP Protokoll: ftp://ftp.rfc-editor.org/in-notes/rfc793.txt (RFC 793)
-
Power Off schrieb:
Haengt sich der Rechner bloss auf, wird erst nach einer Timeout-Zeit im TCP/IP-Stack bemerkt, dass die Verbindung nicht mehr steht.
nö, nur wenn keep-alives aktiviert sind. sonst bemerkt das sender-tcp es erst, wenn es ein paket versenden will und nach ein paar wiederholungen kein 'ack' kommt.
Power Off schrieb:
Ich kenne das TCP/IP-Protokoll nicht gut genug, um sagen zu koennen, ob z.B. der Empfang eines Pakets bestaetigt wird, oder ob es eine Keep-Alive-Sequenz gibt, die prueft, ob der Empfaenger noch vorhanden ist.
gibt es, aber das ist optional (die meisten tcp-stacks können es aber). dabei wird das letzte bestätigte byte nochmal bestätigt
Power Off schrieb:
GNU/Linux ist da wesentlich besser als z.B. Windows. Verbindungsaufbau und -Trennung geht schneller, und viele Zustaende werden sofort bemerkt.
das sind mal wieder nur gerüchte
-
net schrieb:
das sind mal wieder nur gerüchte
Na ja, war halt mein Eindruck, hab schon mehrmals TCP/IP encapsulation layer fuer verschiedene Plattformen geschrieben, und die UNIXe (Linux, AIX, Solaris) waren mir lieber als Windows, obwohl ich mich mit Windows besser auskenne.
connect()s dauern bei Windows extrem lang. Deshalb hab ich immer mit non-blocking Sockets und asynchronous completion gearbeitet (auch bei Windows). War mir zu riskant, einen Thread auf unbestimmte Zeit zu blockieren. Bei non-blocking Sockets kann auch bei send() und recv() nix blockieren.
Die TCP/IP Performance ist bei UNIXen definitiv hoeher (mein Eindruck).
-
Da keine physische Verbindung zwischen Sockets stattfindet kann der Server nur durch senden herausfinden ob es den Client noch gibt.
Server sendet ein Packet an den Socket. Kernel weiß das dieses Packet von diesem Socket an IPADRESSE X auf Port Y gehen soll und stellt das Packet zusammen. Jetzt sendet er alles an seine Netzwerkkarte welche es weiter ins INET transpotiert. Anhand des Headers wissen alle wo es hingehört. Am Client empfängt der Kernel dieses Packet und speichert es (sendet gegebenefalls Meldungen auch an den Server zurück). Das Clientprogramm holt sich vom Kernel dieses Packet.
Sollte der Client nicht mehr da sein bekommt der Server auch keine Meldung mehr. Somit beendet er die Socketverbindung je nach Implementierung (Gegebenenfalls versucht er es X-Mal nochmals).
Und bevor jetzt kommt das hier auf verschiedenen OSI-Schichten noch mehr passiert. Ich habe eine einfache erklärung gegeben wie das überhaupt mit den Sockets geht.
Nicht der Client sendet über den Treiber Daten sondern der Kernel macht dies.
Der Client/Server kommuniziert nur mit Datenstucts des Kernels.
-
Power Off schrieb:
connect()s dauern bei Windows extrem lang.
Deshalb hab ich immer mit non-blocking Sockets und asynchronous completion gearbeitet (auch bei Windows). War mir zu riskant, einen Thread auf unbestimmte Zeit zu blockieren.das kann sein. bei windows muss man manchnmal ein paar einstellungen in der registry ändern. z.b arbeitet windows mit 'delayed acks' um die netzwerklast zu minimieren. das ist schlecht, wenn man viele kleine informationen möglichst schnell verschicken will. lässt sich aber abstellen
Power Off schrieb:
Bei non-blocking Sockets kann auch bei send() und recv() nix blockieren.
naja, aber die daten gehen ja doch erst raus, wenn die verbindung aufgebaut wurde. mit nonblocking socks kannste aber wenigstens mit send() den socket-ausgangspuffer schon mal vollschreiben während die verbindungsaufnahme im gang ist.
Power Off schrieb:
Die TCP/IP Performance ist bei UNIXen definitiv hoeher (mein Eindruck).
also bei sowas wie solaris kann ich mir schon vorstellen, dass sun das extrem optimiert hat. man kann z.b. bei empfangenen paketen auf den prüfsummenvergleich verzichten wenn das bitübertragungs-protokoll sowieso schon einen check macht. ..aber es gibt ja viele verschiedene szenarien z.b. tcp über ethernet, über ppp, etc. viele kleine pakete in 'echtzeit' oder grosse datenmengen uswusw... windows versucht dabei immer den besten mittelweg zu finden und das ist natürlich für extremfälle nicht optimal
-
danke klappt
ich sende jetzt einfach alle 5 sekunden ne leere zeichenkette und wenn der client getrennt wurde gibt send beim zweiten (warum auch immer?) versuch -1 zurück
das SIPIPE signal nicht vergessen sonst verabschiedet sich der server
-
debian inside schrieb:
ich sende jetzt einfach alle 5 sekunden ne leere zeichenkette und wenn der client getrennt wurde gibt send beim zweiten (warum auch immer?) versuch -1 zurück
beim ersten send() landen die daten erstmal im sendepuffer. der eigentliche sendevorgang kommt etwas später. der schlägt fehl. erst beim zweiten send() "weiss" der socket, dass die verbindung wech ist.