Linux Socket: Wie erkennen getrennt Netzwerk in ein client-Programm?
Ich bin Debuggen eines c-basierten linux-socket-Programm. Wie alle Beispiele in Webseiten,
Ich habe die folgende Struktur:
sockfd= socket(AF_INET, SOCK_STREAM, 0);
connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
send_bytes = send(sockfd, sock_buff, (size_t)buff_bytes, MSG_DONTWAIT);
Kann ich erkennen, das Trennung, wenn die entfernen-server schließt seine server-Programm. Aber wenn ich ziehen Sie das ethernet-Kabel, die send-Funktion noch zurück, positive Werte eher als -1.
Wie kann ich überprüfen Sie die Netzwerkverbindung in einer client-Programm, vorausgesetzt, ich kann es nicht ändern server-Seite?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zunächst einmal sollten Sie wissen
send
eigentlich nicht, schicken Sie alles, es ist nur eine Speicher-kopieren-Funktion/system aufrufen. Es kopiert Daten aus dem Prozess in den kernel - irgendwann später wird der kernel Holen, die Daten und senden Sie es auf die andere Seite nach Verpackung in Segmente und Pakete. Dahersend
kann nur einen Fehler zurück, wenn:Der wichtigste Punkt ist, dass
send
senden nichts und daher seiner Rückkehr-Codes nicht sagen, nichts über die Daten tatsächlich an die andere Seite.Zurück zu deiner Frage, wenn TCP Daten sendet, erwartet es eine gültige Anerkennung in einer angemessenen Höhe der Zeit. Wenn es nicht, es sendet. Wie oft kommt es erneut ? Jede TCP-stack anders, aber die norm ist die Verwendung von exponentiellen backoffs. Das heißt, zuerst 1 Sekunde warten, dann 2, dann 4 und so weiter. Auf einige Stapel dieser Vorgang kann einige Minuten in Anspruch nehmen.
Der wichtigste Punkt ist, dass im Falle einer Unterbrechung der TCP-wird erklären, eine Verbindung tot nur nach einem ernsthaft großen Zeit der Stille (auf Linux ist es nicht so etwas wie 15 Wiederholungen - mehr als 5 Minuten).
Einen Weg, um dieses Problem zu lösen, ist die Implementierung einiger Anerkennung Mechanismus in der Anwendung. Sie könnte zum Beispiel das senden einer Anforderung an den server "Antwort innerhalb von 5 Sekunden, oder ich werde erklären, dass diese Verbindung tot" und dann
recv
mit einem timeout.Zu erkennen, eine remote-Verbindung trennen, tun ein
read()
Prüfen Sie diesen thread für mehr Infos:
Lesen kann () - Funktion, die auf einem verbundenen socket return null bytes?
Können Sie nicht erkennen, das unplugged ethernet-Kabel nur mit dem Aufruf write() funcation.
Das ist, weil der tcp-Neuübertragung gehandelt, indem Sie den tcp-stack ohne Ihr Bewusstsein.
Hier sind Lösungen.
Obwohl Sie bereits keepalive-option für Ihre Anwendung-Buchse, können Sie nicht erkennen, in der Zeit die Toten Zustand der Verbindung von der Steckdose, im Falle Ihrer app schreibt auf den socket.
Das ist, weil der tcp-Neuübertragung durch den kernel tcp-stack.
tcp_retries1 und tcp_retries2 kernel-Parameter für die Konfiguration von tcp-retransmission-timeout.
Es ist schwer, vorherzusagen, die genaue Zeit der Weiterverbreitung timeout, weil es errechnet sich durch die RTT-Mechanismus.
Sehen Sie diese Berechnung in rfc793. (3.7. Daten-Kommunikation)
https://www.rfc-editor.org/rfc/rfc793.txt
Einzelnen Plattformen mit kernel-Konfigurationen für tcp-Neuübertragung.
http://linux.die.net/man/7/tcp
http://www.hpuxtips.es/?q=node/53
http://www-903.ibm.com/kr/event/download/200804_324_swma/socket.pdf
Sollten Sie niedrigeren Wert für tcp_retries2 (standardmäßig 15), wenn Sie wollen früh erkennen und Toten Verbindung, aber es ist nicht die genaue Zeit, wie ich bereits sagte.
Zusätzlich, Sie können derzeit nicht die Werte einstellen, die nur für single-socket. Das sind Globale kernel-Parameter.
Es gab einige Test anwenden Weiterverbreitung tcp-socket-option für single-socket(http://patchwork.ozlabs.org/patch/55236/), aber ich glaube nicht, dass es angewendet wurde, in die kernel-mainline. Ich kann nicht finden, diese Optionen definition in system-header-Dateien.
Für Referenz-monitor können Sie Ihre socket-option keepalive durch 'netstat --Timer' wie unten.
https://stackoverflow.com/questions/34914278
Darüber hinaus, wenn die keepalive-timeout ocurrs, treffen Sie auf verschiedene Ereignisse zurück, die je auf Plattformen, die Sie verwenden, so müssen Sie sich nicht entscheiden dead connection status nur durch Rücksendung Veranstaltungen.
Zum Beispiel, HP gibt POLLERR Ereignis und AIX gibt nur POLLIN-Ereignis aus, wenn die keepalive-timeout Auftritt.
Treffen Sie ETIMEDOUT Fehler bei recv () - Aufruf in dieser Zeit.
In den letzten kernel-version(seit 2.6.37), die Sie verwenden können, TCP_USER_TIMEOUT option wird gut funktionieren. Diese option kann verwendet werden, für single-socket.
Schließlich können Sie mit read-Funktion mit MSG_PEEK-flag, das lassen Sie überprüfen, dass die Steckdose in Ordnung ist. (MSG_PEEK nur blicken wenn Daten angekommen auf kernel-stack-Puffer und nie kopiert die Daten in Benutzer-Puffer.)
So können Sie dieses flag nur für die überprüfung der Steckdose in Ordnung ist, ohne jegliche Nebenwirkung.
Den Rückgabewert überprüfen, und sehen, ob es gleich diesem Wert:
Fügen Sie auch einen Scheck für den SIGPIPE-signal in Ihren handler, um es besser kontrollieren zu können.