Hey Bande. Ich habe gerade einen Client und Server in C ++ mit sys / socket geschrieben. Ich muss eine Situation behandeln, in der der Client noch aktiv ist, aber der Server nicht verfügbar ist. Eine vorgeschlagene Möglichkeit besteht darin, einen Heartbeat zu verwenden, um Konnektivität regelmäßig zu bestätigen. Und wenn es keine gibt, versuchen Sie, alle X Sekunden für Y Zeitraum neu zu verbinden, und dann zu Zeitüberschreitung.
Ist dieser "Herzschlag" der beste Weg, um die Konnektivität zu überprüfen?
Der Socket, den ich verwende, hat möglicherweise Informationen darüber. Gibt es eine Möglichkeit, zu überprüfen, ob eine Verbindung besteht, ohne den Puffer zu stören?
Wenn Sie TCP-Sockets über ein IP-Netzwerk verwenden, können Sie die Keepalive-Funktion des TCP-Protokolls verwenden, die den Socket regelmäßig überprüft, um sicherzustellen, dass das andere Ende immer noch da ist. (Dies hat auch den Vorteil, dass der Weiterleitungsdatensatz für Ihren Socket in jedem NAT-Router zwischen Ihrem Client und Ihrem Server gültig bleibt.)
Hier ist eine TCP Keepalive-Übersicht , in der einige der Gründe aufgeführt sind, warum Sie TCP verwenden sollten bleib am Leben; Dieses Linux-spezifische HOWTO beschreibt, wie Sie Ihren Socket für die Verwendung von TCP Keepalive zur Laufzeit konfigurieren.
Sie können TCP Keepalive in Windows-Sockets aktivieren, indem Sie SIO_KEEPALIVE_VALS
mithilfe der WSAIoctl () Funktion.
Wenn Sie UDP-Sockets über IP verwenden, müssen Sie einen eigenen Heartbeat in Ihr Protokoll einbauen.
Wenn die andere Seite verschwunden ist (d. h. der Prozess ist verstummt, das Gerät ist heruntergefahren usw.), sollte der Versuch, Daten vom Socket zu empfangen, zu einem Fehler führen. Wenn die andere Seite jedoch nur aufgehängt wird, bleibt der Sockel geöffnet. In diesem Fall ist es nützlich, einen Herzschlag zu haben. Stellen Sie sicher, dass jedes Protokoll, das Sie (zusätzlich zu TCP) verwenden, irgendeine Art von "Nichts machen" -Anforderung oder Paket unterstützt - jede Seite kann dies verwenden, um zu verfolgen, wann sie zum letzten Mal etwas von der anderen Seite erhalten haben Schließen Sie die Verbindung, wenn zwischen den Paketen zu viel Zeit verstreicht.
Beachten Sie, dass Sie davon ausgehen, dass Sie TCP / IP verwenden. Wenn Sie UDP verwenden, dann ist das ein ganz anderer Kessel Fisch, da es verbindungslos ist.
Ok, ich weiß nicht, was dein Programm macht oder so, also ist das vielleicht nicht machbar, aber ich schlage vor, dass du versuchst, den Sockel immer offen zu halten. Es sollte nur geöffnet sein, wenn Sie es verwenden, und sollte geschlossen sein, wenn Sie es nicht sind.
Wenn Sie zwischen Lese- und Schreibvorgängen stehen, die auf Benutzereingaben warten, schließen Sie den Socket. Entwerfen Sie Ihr Client / Server-Protokoll (vorausgesetzt, Sie tun dies manuell und verwenden keine Standardprotokolle wie http und / oder SOAP), um damit umzugehen.
Sockets werden fehlerhaft, wenn die Verbindung unterbrochen wird; Schreiben Sie Ihr Programm so, dass Sie bei einem solchen Fehler beim Schreiben in den Socket keine Informationen verlieren und im Falle eines Fehlers beim Lesen aus dem Socket keine Informationen erhalten. Transactionality und Atomicity sollten in Ihr Client / Server-Protokoll gerollt werden (vorausgesetzt, Sie entwickeln es selbst).
Ja, dieser Herzschlag ist der beste Weg. Sie müssen es in das Protokoll einbauen, das der Server und der Client für die Kommunikation verwenden.
Die einfachste Lösung besteht darin, dass der Client Daten regelmäßig sendet und der Server die Verbindung schließt, wenn er in einem bestimmten Zeitraum keine Daten vom Client erhalten hat. Dies funktioniert perfekt für Abfrage- / Antwortprotokolle, bei denen der Client Abfragen sendet und der Server Antworten sendet.
Sie können beispielsweise das folgende Schema verwenden:
Der Server antwortet auf jede Anfrage. Wenn der Server für zwei Minuten keine Abfrage empfängt, wird die Verbindung geschlossen.
Der Client sendet Abfragen und hält die Verbindung nach jedem geöffnet.
Wenn der Client eine Abfrage für eine Minute nicht gesendet hat, sendet er eine "Sie sind da" -Abfrage. Der Server antwortet mit "Ja, ich bin". Dies setzt den Zwei-Minuten-Timer des Servers zurück und bestätigt dem Client, dass die Verbindung noch verfügbar ist.
Es kann einfacher sein, wenn der Client die Verbindung nur schließt, wenn er keine Abfrage für die letzte Minute senden muss. Da alle Operationen vom Client initiiert werden, kann er immer nur eine neue Verbindung öffnen, wenn er eine neue Operation ausführen muss. Das reduziert es auf genau das:
Der Server schließt die Verbindung, wenn er innerhalb von zwei Minuten keine Abfrage erhalten hat.
Der Client schließt die Verbindung, wenn er innerhalb einer Minute keine Abfrage senden musste.
Dies stellt jedoch dem Client nicht sicher, dass der Server jederzeit vorhanden und bereit ist, eine Abfrage zu akzeptieren. Wenn Sie diese Fähigkeit benötigen, müssen Sie eine "Sind Sie dort" -Abfrage / Antwort in Ihr Protokoll implementieren.
vielleicht wird Ihnen das helfen, TCP Keepalive HOWTO oder diese SO_SOCKET