(28.05.2014 14:00 )FEL schrieb: (28.05.2014 11:51 )Kiesch schrieb: Und die weiteren Sendeversuche werden dann beliebig oft wiederholt auch über den Timeout hinaus?
Nein nicht beliebig oft. Max. 4 Wiederholungen habe ich gezählt, wobei die Zeit zwischen den Versuchen immer gößer wurde (z.B.: 0,5s; 1s; 2s; 4s).
Das Protokoll, welches verwendet wird, ist sehr "mistig". Es setzt vorraus, das jeder Befehl in einem separaten TCP-Frame gesendet wird. Dumm gelaufen, wenn man auf OSI Schicht 7 sitzt und keine Kontrolle über die Paketzusammensetzung hat. Deswegen wird der Nagle-Algorithmus abgeschaltet. Dies wird über die "wsock32.dll" realisiert.
Ich hatte gehofft, es gibt "Low Level" TCP-Funktionen, über die man einen Verbindungsabbruch erkennen kann.
Die gibts eben nicht weil das TCP/IP Protokoll nicht so designt ist. Wenn eine Verbindung zustandekommt (Connection Request positiv befestigt) dann ist diese Verbindung erst mal einfach als gültig erkannt. Wenn eine Applikation an die Socketlibrary dann einen Buffer schickt um den zu versenden meldet diese Socketlibrary ganz einfach brav zurück dass das alles super erfolgreich war. Der Buffer wurde akzeptiert und die Verbindung wurde von der Gegenseite bis zu dem Zeitpunkt nicht terminiert also ist alles in Ordnung. Danach versucht die Socketlibrary um den Buffer zu verschicken, resp. sie tut es auch. Wenn sich in der Zwischenzeit die Gegenstation sang- und klanglos verabschiedet hat, ohne die Verbindung aktiv zu terminieren, läuft dieses Packet einfach ins Leere ohne dass die Socketlibrary das direkt sieht. Sie merkt es dann nach einiger Zeit weil das Packet nicht bestätigt wurde, aber das kann viele Gründe haben, also wird nicht gleich aufgegeben sondern mehrmals versucht das Packet nochmals zu verschicken. Das kann mit den Timeouts, die ja auch nicht zu kurz sein dürfen da eine Internetverbindung über einen Satallieten und/oder noch schlimmer eine 9600 Baud Modem Verbindung schon mal einige Sekunden Turnaroundtime haben kann, schnell mal mehr als eine Minute dauern. Erst dann beginnt die Socketlibrary anzunehmen dass die Gegenstelle vielleicht doch nicht mehr lebt und beginnt damit das Socket ihrerseits zu schliessen.
Die einzige Art um selber aktiv festzustellen dass die Gegenstelle wohl nicht mehr lebt ist um ein Kommando zu schicken und wenn die Antwort nicht innerhalb vernünftiger Zeit erfolgt (einige 100ms in einem lokalen Netzwerk aber mehrere Sekunden in Internetverbindungen) die Verbindung selber aktiv zu schliessen und wieder neu zu öffnen versuchen. Diese Art von Netzwerkkommunikation kann sehr zuverlässig sein, hat aber noch immer einige Sekunden Timeout bevor man das sang- und klanglose Verschwinden der Gegenstelle erkennen kann.