Wie zu erkennen, eine TCP-socket-Trennung (mit C Berkeley-socket)
Ich bin mit einer Schleife zu Lesen, die Botschaft von einem c-Berkeley-socket-aber ich bin nicht in der Lage zu erkennen, Wann der Steckdose getrennt ist, so würde ich das akzeptieren einer neuen Verbindung. bitte helfen Sie
while(true) {
bzero(buffer,256);
n = read(newsockfd,buffer,255);
printf("%s\n",buffer);
}
InformationsquelleAutor Ayoub M. | 2011-06-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nur so kann man erkennen, dass ein socket verbunden ist, ist durch schreiben.
Immer eine Fehlermeldung auf
read()/recv()
wird angegeben, dass die Verbindung unterbrochen ist, aber nicht immer einen Fehler beim Lesen bedeutet nicht, dass die Verbindung aufgebaut ist.Können Sie daran interessiert, lese das hier:
http://lkml.indiana.edu/hypermail/linux/kernel/0106.1/1154.html
Darüber hinaus, mit TCP Keep-Alive können helfen, zu unterscheiden zwischen inaktiven und unterbrochene verbindungen (durch das senden etwas in regelmäßigen Abständen, auch wenn keine Daten gesendet werden, von der Anwendung).
(EDIT: Entfernt, falscher Satz, wie bereits von @Damon, danke.)
es gibt keinen Unterschied zwischen " nicht immer alles, weil nichts gesendet wurde, und nicht immer etwas, da der link kaputt ist. (Es ist ein Allgemeines Prinzip in der Tat. Wenn Sie nicht bekommen, kein Brief in den morgen, entweder niemand schickte Sie nichts oder das post-system nicht funktioniert: Sie können nur herausfinden, was die Ursache ist, indem Sie versuchen etwas senden per post, mehr oder weniger.) Dies ist der Grund, warum Sie brauchen, um zu behandeln timeouts bei der Verwendung von TCP-verbindungen. Eine Verbindung, die abrupt geschlossen wird einfach nicht senden, Sie nichts zu sagen, Sie seine Schließung, weil Sie es nicht können.
sicher, es gibt vielleicht eine Verzögerung, aber das ist die einzige Möglichkeit zu erkennen, eine Trennung, immer noch. Spülen Sie den Puffer, wenn Sie brauchen, um so bald wie möglich wissen. (Wenn Sie warten, Lesen Sie Fehler, können Sie warten, für eine wirklich lange Zeit... und das wäre nicht zuverlässig.)
es ist eine abrupte Unterbrechung, mit schreiben auch hilflos, richtig?" Nein, es ist nicht hilflos, sollte es fehlschlägt, damit Sie erkennen können, eine Unterbrechung. Ihre Idee erwarten einen Takt alle 15 sec ist anders, es könnte eine längere Verzögerung, ohne die Verbindung zu schließen. Sie sind dann eine willkürliche Entscheidung, was die Verzögerung, die Sie annehmbar finden, das ist es (und das ist oft das richtige zu tun, praktisch), aber das macht nicht wirklich sagen, ob der socket wurde getrennt, es bedeutet nur, Sie geben und nehmen, die es hat.
ja, abrupte in diesem Sinne (komplett packet loss ohne Warnung). Wenn nichts gemeint ist, gesendet werden, können Sie nicht wissen, ob Sie gemeint sind, etwas zu erhalten (daher die Idee hearbeat in das Protokoll, wie Sie vorgeschlagen, für Protokolle, Unterstützung). Der einzige Weg, um herauszufinden, ob es getrennt ist, zu versuchen, zu schreiben. Versuchen, etwas zu Lesen, ob Sie nicht wissen, ob it ' s meant to geschickt haben, alles wird Ihnen nichts verraten oder so. Ihr Fall ist anders, da Sie eine asynchrone schreiben. Ich weiß nicht, zu steigern.asio-sehr gut, aber versuchen Sie Spülen Sie den Puffer sofort, wenn Sie können.
InformationsquelleAutor Bruno
Dein problem ist, dass Sie völlig ignorieren-Ergebnis
read()
. Deinem code nachread()
Aussehen sollte zumindest so:Und die Annahme einer neuen Verbindung erfolgt in einem separaten thread, nicht angewiesen auf das Ende des Stroms auf diese Verbindung.
Den
bzero()
rufen ist sinnlos, nur ein workaround für frühere Fehler.InformationsquelleAutor user207421
,Weil Sie nicht verwenden keepalive-timeout.
In Empfängerseite, die socket-option keepalive ist die beste Lösung für die Erkennung von dead-Verbindung.
Aber, im Falle der Anwendung weiter zu schreiben-Buchse, es ist etwas zu denken.
Auch wenn 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 '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.
reD()
.InformationsquelleAutor cloudrain21