Hallo Liebe Freunde,
Ich habe zwei einfache TCP / IP-Anwendungen, die mit der
Winsock2-Bibliothek programmiert sind.
Der erste ist in einem Laptop installiert und arbeitet als Server und
der andere in einem zweiten Laptop und arbeitet als Client. Bisher
funktioniert alles gut.
Ich habe folgendes Problem:
Wenn ich das Kabel abziehe oder wenn einer der Laptops im WIFI-Modus
verschwindet.
Die Verbindung wird unterbrochen und die Funktionen send () und rcv ()
der Winsock-Standardbibliothek geben Fehler zurück, was normal ist.
Mein Ziel:
Ich möchte, dass die Verbindung automatisch wiederhergestellt wird, wenn
ich das Kabel wieder anschließe oder wenn sich die beiden Laptops
nähern.
Wie mache ich das?
Ich bedanke mich herzlich für eure Inputs
Da muss dann eine nicht-triviale Fehlerbehandlung eingreifen.
Die einfachste Methode versucht auf dem Client erneutes connect() mit
neuem Socktet. Falls das fehlschlägt nach kurzer Pause wiederholen.
Das will man aber nicht wirklich selber programmieren sondern eine
vorhandene Bibliothek benutzen. Heutzutage geht man meistens noch einen
Schritt weiter und macht das Ganze dann via HTTP. Oftmals sind HTTP Libs
einfacher zu benutzen als reine TCP/IP Libs.
Jim M. schrieb:> Heutzutage geht man meistens noch einen> Schritt weiter und macht das Ganze dann via HTTP. Oftmals sind HTTP Libs> einfacher zu benutzen als reine TCP/IP Libs.
Habe ich was nicht mitbekommen, woher weißt du welche Art von Daten der
TO senden will? Im Post lese ich davon jedenfalls nichts. Sicher es gibt
Daten welche man Wunderbar als Http Stream senden kann, aber es gibt
auch viele bei den das nötiger Overhead ist, die in Http zu zwängen,
ansonsten hätten Websockets keine Daseinsberechtigungen.
Aber Verallgemeinerungen Treffen meistens zu ;) und Linux ist
grundsätzlich besser als Windows!
Hi Mike,
Hast Du das Problem schon gelöst?
Ohne genauer zu wissen, wie der Ablauf ist und wie Du programmiert hast
bzw. kannst und willst, ist es schwer, Dir einen Rat zu geben.
Hier mal ein Beispiel:
Client und Server sind per Patchkabel an einen Switch angeschlossen und
die tcp Verbindung besteht.
Jetzt wird das Patchkabel am Client abgezogen. Damit ist am Client der
Link weg und bei Standardeinstellung des Notebooks auch das Netz. Der
Server bekommt davon erst mal nichts mit und dort ist noch „alles in
Ordnung“.
Der Client wird den Abbruch erkennen. Sofort, wenn er zuletzt recv
aufgerufen hat, also auf Daten wartet, spätestens aber beim nächsten
send Aufruf.
Der Server wird zunächst nicht abbrechen. Wenn er Daten sendet oder
Daten gesendet hat, die noch nicht quittiert sind, wird die tcp
Verbindung nach etlichen Paketwiederholungen zig Sekunden später erst
abbrechen. Wenn nichts unquittiert ist und er auch nichts sendet bleibt
die Verbindung bestehen.
Wenn die Verbindung auf der Server Seite auch abbricht, dann bekommt das
das Serverprogramm auch mit. Es wird mit einem recv Aufruf auf Daten
warten und der recv Aufruf kommt dann mit Fehler zurück.
Wenn der Server nichts gesendet hat und nur auf Daten wartet, wird er
„ewig“ warten.
Das wäre also ein mögliches Abbruchszenario gewesen für einen
Netzausfall beim Client. Wie sieht es in dem Fall mit dem Wiederanlauf
aus?
Auch das hängt davon ab, wie programmiert wird. Im einfachsten Fall,
wenn es auch beim Server zum Abbruch gekommen ist, dann reicht es, auf
dem Server eine Schleife zu programmieren, in der er wieder auf den
accept läuft und die Client Verbindung wieder übernehmen kann. Der
Client könnte dann so programmiert werden, dass er nach dem Abbruch alle
x Sekunden wieder versucht die Verbindung aufzubauen.
Wenn der Server vom Abbruch nichts gemerkt hat, die „alte“ Verbindung
dort also noch existiert, dann kommt es eben darauf an, wie er
programmiert wurde.
Wenn er den Socket im Listen Mode lässt, wird das Betriebssystem die
neue Verbindung annehmen und der Client kann seinen Request senden.
Wenn der Listen Socket geschlossen wurde (weil der Server sowieso nur
eine Verbindung bearbeiten sollte), dann wird das System die neue
Verbindung mit Reset abweisen. Es kommt also keine neue Verbindung
zustande.
Wenn der Listen Socket aktiv geblieben ist, wird die neue Verbindung
immer angenommen und das System schreibt die vom Client gesendeten Daten
in den receive buffer. Das macht das Betriebssystem ohne das
Serverprogramm dafür zu bemühen. Das Serverprogramm muss dann so
programmiert werden, dass es die neue Verbindung übernimmt, die alte
beendet und auf der neuen mit dem Client kommuniziert.
Das wäre also ein mögliches Wiederanlauf-Szenario.
Einfacher ist der Wiederanlauf offenbar, wenn die Verbindung auf beiden
Seiten abbricht. Das kann man für einen solchen Fall so regeln, wie es
üblicherweise immer geregelt wird: Mit tcp keep alive Paketen. Das muss
man im Betriebssystem einschalten (ich nehme an, dass das bei Windows
standardmäßig eingeschaltet ist) und im Serverprogramm per Socket
Option aktivieren. Weil keep alive Standardeinstellungen in der Regel im
Stundenbereich liegen, muss man auch noch die Zeitparameter anpassen,
damit die Verbindung bei unbeantworteten keep alive Paketen so schnell
abbricht, wie man es braucht. Dazu gibt es aber bei Microsoft ganz
sicher ausreichend Dokumentation.
Schönes Wochenende und erfolgreiches Socket Programmieren
> Die Verbindung wird unterbrochen und die Funktionen send () und rcv ()> der Winsock-Standardbibliothek geben Fehler zurück, was normal ist.
Nun ja, "normal" ist so ne Sache. Soweit ich mich erinnern kann, hat
Standard-Windows das merkwürdige (oder eher schwachsinnige) Verhalten,
alle an ein Interface gebundene Sockets zu schließen, wenn dessen Link
down geht. Kabel kurz rausziehen und wieder einstecken - alle Sockets
tot. Ich glaube, das konnte man umschalten, so dass es sich wie alle
anderen Systeme verhält: retry, retry, retry, timeout, error; weiß aber
nicht mehr wie.
> Mein Ziel:> Ich möchte, dass die Verbindung automatisch wiederhergestellt wird, wenn> ich das Kabel wieder anschließe oder wenn sich die beiden Laptops> nähern.> Wie mache ich das?
Mit normalen TCP geht das nicht transparent: Daten gehen dabei verloren
und die Anwendung muß den Datenverlust irgendwie behandelt. Da braucht
es sowohl Client- als auch Serverseitigen Support. Wie komplex das ist,
kommt auf die Anwendung an - von trivial bis unmöglich.
Multi-Path-TCP (MPTCP) soll das Problem transparent lösen, ohne
Anwendungen modifizieren zu müssen. Ob das bei dir eine Option ist,
musst du mal nachschauen - vermutlich nicht.
foobar schrieb:> Soweit ich mich erinnern kann, hat> Standard-Windows das merkwürdige (oder eher schwachsinnige) Verhalten,> alle an ein Interface gebundene Sockets zu schließen, wenn dessen Link> down geht.
Der Sinn davon erschliesst sich bei Notebooks. Wenn der Rechner auch im
WLAN drin ist, und es mit gezogenem Stecker praktisch sofort weiter
geht. Da damit eine andere IP-Adresse verbunden ist, geht die Verbindung
sowieso koppheister, dafür aber sofort. Die Anwendung kriegt es mit und
kann ggf neu verbinden. Ohne diese Methode dauert das viel länger.