Forum: PC-Programmierung [C++] Client <-> Server Verbindung: Server Ausfall erkennen?


von Stefan (Gast)


Lesenswert?

Guten Morgen Gemeinde.

Kurze Frage zu C++:
Bei einer erfolgreich aufgebauten Socket-Verbindung (Server <-> Client) 
kann es in einigen Fällen passieren, dass der Server plötzlich die 
Verbindung kappt, da das Programm auf einem anderen Rechner korrekt 
beendet wird (oder auch abstürzt).

Wie bekomme ich das Client-seitig nun mit? Und welche Dinge sind danach 
zu beachten? Genügt ein schlichtes close()?

Optional:
Den Client setzen ich danach wieder genau wie beim ersten Mal auf, damit 
dieser bereit ist, falls der Server "zurückkehrt"?

DANKE!

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Stefan schrieb:
> Wie bekomme ich das Client-seitig nun mit?

Schlimmstenfalls bekommst du beim nächsten Schreib- oder Leseversuch 
nach einem eventuell sehr langen Timeout einen Fehler. Welcher es war 
siehst du in errno. Anhand errno prüfst du ob es wirklich ein fataler 
Fahler ist (nicht EAGAIN oder vergleichbare Fehler).

Ist die Verbindung wirklich weg, gibst du sorgfältig alle Resourcen frei 
und beginnst von Vorne.

> Den Client setzen ich danach wieder genau wie beim ersten Mal auf, damit
> dieser bereit ist, falls der Server "zurückkehrt"?

Du kannst so lange keine neue Verbindung aufsetzen solange der Server 
nicht da ist. D.h. du bekommst beim Verbindungsaufbau Fehler. Da ist 
nichts mit "bereit sein", sondern nur mit immer wieder versuchen. 
Geschickterweise nicht alle paar Millisekunden, sondern mit einer 
Strategie, die anfänglich relativ schnell versucht die Verbindung wieder 
aufzubauen und dann immer langsamer wird, d.h. mit größeren Abständen 
(bis hin zu Minuten oder noch größeren Abständen). Je nach Anwendung 
setzt du eine Grenze der Wiederholungen, z.B. nach Anzahl und Zeit 
begrenzt, bei deren Erreichen du aufgibst.

von Mikro 7. (mikro77)


Lesenswert?

Stefan schrieb:

> Wie bekomme ich das Client-seitig nun mit?

In beiden Fällen bekommst du in der Regel ein EOF (read() liefert 0).

Interessant wird es, wenn der Server selbst abstürzt (dann wird kein FIN 
gesendet). Das merkst du in der Regel erst nach einer Schreiboperation, 
die auf ein Timeout läuft und somit der System API bei der 
darauffolgenden Schreib/Leseoperation die Möglichkeit gibt, einen Fehler 
zu liefern (broken pipe,connection reset by peer, o.ä.). Hängst du in 
einer Leseoperation fest, hilft das Keep-Alive Flag weiter (probing the 
connection at certain intervals).

> Und welche Dinge sind danach zu beachten? Genügt ein schlichtes close()?

Soweit es den Socket (file descriptor) betrifft: ja.

> Optional:
> Den Client setzen ich danach wieder genau wie beim ersten Mal auf, damit
> dieser bereit ist, falls der Server "zurückkehrt"?

Ja. Das schließt alle notwendigen Maßnahmen für verzögerten 
Verbindungsaufbau (delayed accept by the peer) und abgelehnte Connection 
Requests ein.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.