Zeitlimit write->read bei boost::asio?

T_55

Lieutenant
Registriert
Feb. 2013
Beiträge
638
Hallo,

ich frage mich gerade bei Boost.Asio und dem Senden von Daten per TCP/IP folgende Sache:
Wenn ein Programm zwei Dinge sendet, also zwei "write()" hintereinander, was passiert wenn das Zielprogramm nach seinem ersten "read()" Zeit vertrödelt (zB wegen Berechnung) und der Sender schon das zweite "write" ausführt, während das Zielprogramm aber noch nicht beim entsprechenden "read()" ist?

Chronologisch etwa so:
1 .Programm B: read1() -> blockierendes Warten auf A
2. Programm A: write1()
3. Programm B: read1() -> wird durchgeführt.
4. Programm A: write2()
5. Programm B: trödelt nach read1()...

Meine Frage ist, wie lange versucht Programm A ein "write()" ohne ein "read()" der Gegenseite bevor eine Exception geworfen wird?
Oder anders gefragt, wie lange darf ein "read()" hinausgezögert werden, sodass man das "write()" nicht verärgert?
Gibts da ein groben Anhaltspunkt in Millisekunden oder Sekunden? 1ms 10ms 100ms 500ms 1sek 5sek ?
ps: Die Frage bezieht sich auf das normale asio::write und asio::read also nicht auf die asynchronen Varianten.

Grüße
 
T_55 schrieb:
und der Sender schon das zweite "write" ausführt, während das Zielprogramm aber noch nicht beim entsprechenden "read()" ist

Deine beiden Programme A und B kommunizieren nicht direkt miteinander, sondern da hängt noch das Betriebssystem dazwischen und insbesondere die Eigenheiten von TCP/IP. Auf Ebene von TCP gibt es noch einen Empfangspuffer, sodass ein sendendes Programm doch so einiges an Daten losschicken kann, ohne dass das empfangende Programm diese sofort entgegennehmen muss.
 
Danke, ich habe mal versucht das zu simulieren und man kann gar keine Exception provozieren wie ich es falsch angenommen hatte. Insofern scheint write äußerst geduldig zu sein. Es gibt auch nach vielen Minuten keine Exception also scheint es normal kein richtiges Timeout zu geben, das ist im Grunde sehr gut besonders wenn das Ziel verzögert einliest.

Eine spannende andere Erkenntnis durch den Test:
Ich dachte asio::write blockiert bis die Daten bei der Gegenseite empfangen wurden -> Falsch, denn das write blockiert zunächst nicht wenn die Gegenseite es nicht gelesen hat, sondern erst ein darauffolgendes asio::write blockiert dann. Also kann man schlussfolgern asio::write blockiert nur wenn ein voriges asio::write noch nicht von der Gegenseite empfangen wurde.
asio::write scheint demnach vor seiner Durchführung zu schauen ob vorige Aktionen bei der Gegenseite angekommen sind, tut das aber nicht für die eigene Aktion. Insofern kann ein einzelnes asio::write auch nicht zum blockieren genutzt werden um zu verifizieren, dass die Dinge angekommen sind. Irgendwie ist das normale asio::write doch ein bisschen asynchron.
Ist also eine echte Empfangs-Garantie nur möglich, wenn der Empfänger eine manuelle Bestätigung an den Absender zurücksendet (zB ein bool=true)?
 
T_55 schrieb:
Ist also eine echte Empfangs-Garantie nur möglich, wenn der Empfänger eine manuelle Bestätigung an den Absender zurücksendet
Wenn die Logik des Programmablaufes dies erfordert, dann würde ich dies auf jeden Fall so machen und mich nicht auf den Erfahrung eines Tests in einer einzigen, ganz bestimmten Konfiguration verlassen. Dieses Verhalten kann bei einer anderen Version der Boost Lib, des OS, mit einem anderen OS, bei Host-Client auf unterschiedlichen Rechner, was auch immer für einer anderen Konfiguration auch anderes sein, ggf. auch einfach laufzeitabhängig (z.B. wegen der Einstellung des Nagle-Algorithmus, google mal nach tcp_nodelay). Also gilt im Zweifel immer: Play it safe!

Übertrage auch immer an Anfang eines Datenpaketes wie viele Byte diese haben wird, es ist nämlich nicht garantiert das ein Paket mit X Bytes auch als solches ankommt, es kann auch aufgeteilt werden oder ein Paket mit X und danach eines mit Y Byte können gemeinsam als nur ein Paket ankommen.
 
Zurück
Oben