Forum: PC-Programmierung tcp/ip mit winsock : automatische Wiederherstellung der Verbindung


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Mike (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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

von Jim M. (turboj)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Imonbln (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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!

von tcp Abbrecher (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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

von foobar (Gast)


Bewertung
0 lesenswert
nicht lesenswert
> 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.

von (prx) A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
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.

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.