Wenn Daten an den Client gesendet werden, der Client jedoch mit der Ausführung von etwas anderem beschäftigt ist, wie lange stehen die Daten zum Lesen mit recvfrom() zur Verfügung?
Was passiert auch, wenn ein zweites Paket gesendet wird, bevor das erste gelesen wird, das erste verloren geht und das nächste darauf wartet, gelesen zu werden?
(Windows – UDP)
Wenn Daten an den Client gesendet werden, der Client jedoch etwas anderes ausführt, wie lange stehen die Daten zum Lesen zur Verfügung? recvfrom()
?
Für immer oder gar nichtoder bis Sie den Socket schließen oder bis zu einem einzelnen Byte lesen.
Der Grund dafür ist:
UDP liefert Datagramme, oder eben nicht. Das klingt wie Unsinn, ist aber genau das, was es ist.
Ein einzelnes UDP-Datagramm bezieht sich entweder auf genau ein oder mehrere “Fragmente”, bei denen es sich um IP-Pakete handelt (weiter verkapselt in einem “On-the-Wire”-Protokoll, aber das spielt keine Rolle). Der Netzwerkstapel sammelt alle Fragmente für ein Datagramm. Wenn die Prüfsumme eines der Fragmente nicht gut ist oder irgendetwas anderes den Netzwerkstapel unzufrieden macht, das komplette Datagramm wird verworfen, und Sie erhalten nichts, nicht einmal einen Fehler. Du weißt einfach nicht, dass etwas passiert ist.
Wenn alles gut geht, a vollständiges Datagramm wird in den Empfangspuffer gestellt. Nie weniger und nie mehr. Wenn Sie es versuchen recvfrom
später bekommst du das.
Der Empfangspuffer ist natürlich notwendigerweise groß genug, um mindestens ein Datagramm mit maximaler Größe (65535 Bytes) zu halten, aber da Datagramme normalerweise nicht die maximale Größe haben, sondern etwas unter 1280 Bytes (oder 1500, wenn Sie so wollen), kann er normalerweise halten einige davon (auf den meisten Plattformen ist der Puffer standardmäßig auf etwa 128-256 KB eingestellt und konfigurierbar).
Wenn im Puffer nicht mehr genügend Platz vorhanden ist, wird das Datagramm verworfen und Sie erhalten nichts (also du tun erhalten Sie noch diejenigen, die sich bereits im Puffer befinden). Wieder wissen Sie nicht einmal, dass etwas passiert ist.
Jedes Mal, wenn Sie anrufen recvfrom
a vollständiges Datagramm wird aus dem Puffer entfernt (wichtiges Detail!), und Sie erhalten die angeforderte Anzahl von Bytes. Das heißt, wenn Sie naiv versuchen, ein paar Bytes zu lesen und dann noch einmal ein paar Bytes, wird es einfach nicht funktionieren. Der erste Lesevorgang verwirft den Rest des Datagramms, und die nachfolgenden lesen die ersten Bytes einiger zukünftiger Datagramme (und möglicherweise Blöcke)!
Das ist sehr verschieden davon, wie TCP funktioniert. Hier können Sie tatsächlich ein paar Bytes lesen und wieder ein paar Bytes, und es wird nur funktionieren, weil die Vermittlungsschicht einen simuliert Datenstrom. Du gibst einen Mist wie es funktioniert, weil der Netzwerkstack dafür sorgt, dass es funktioniert.
Was passiert auch, wenn ein zweites Paket gesendet wird, bevor das erste gelesen wird, geht das erste verloren und das nächste wartet darauf, gelesen zu werden?
Sie wollten wahrscheinlich eher “empfangen” als “gesendet” sagen. Senden und Empfangen haben unterschiedliche Puffer, das würde also überhaupt nichts ausmachen. Informationen zum Empfangen eines weiteren Pakets, während sich noch eines im Puffer befindet, finden Sie in der obigen Erklärung. Wenn der Puffer das zweite Datagramm aufnehmen kann, wird es gespeichert, andernfalls geht es stillschweigend *puh*.
Bereits im Puffer befindliche Datagramme sind davon nicht betroffen.
Normalerweise werden die Daten gepuffert, bis sie gelesen werden. Ich nehme an, wenn Sie lange genug warten, dass der Treiber keinen Platz mehr hat, muss es reichen etwasaber vorausgesetzt, Ihr Code funktioniert halbwegs vernünftig, das sollte kein Problem sein.
Ein typischer Netzwerktreiber ist in der Lage, eine Reihe von Paketen zu puffern, ohne eines zu verlieren.
Wenn Daten an den Client gesendet werden, der Client jedoch mit der Ausführung von etwas anderem beschäftigt ist, wie lange stehen die Daten zum Lesen mit recvfrom() zur Verfügung?
Dies hängt vom Betriebssystem ab, in Windows glaube ich, dass die Standardeinstellung für jeden UDP-Socket 8012 ist, dies kann mit setsockopt () ausgelöst werden. Winsock-Dokumentation Solange der Puffer also nicht voll ist, bleiben die Daten dort, bis der Socket geschlossen oder gelesen wird.
Was passiert auch, wenn ein zweites Paket gesendet wird, bevor das erste gelesen wird, das erste verloren geht und das nächste darauf wartet, gelesen zu werden?
Wenn der Puffer Platz hat, werden sie beide gespeichert, wenn nicht, wird einer von ihnen verworfen. Ich glaube, es ist das neueste, aber ich bin mir nicht 100% sicher.
Sobald die Daten tatsächlich den Zielcomputer erreichen, würde ich davon ausgehen, dass sie ähnlich wie TCP-Verkehr behandelt werden – das Datagramm wird irgendwo in einem Puffer liegen, in der Reihenfolge, in der die Datagramme angekommen sind, bis es gelesen wird. (Ein voller Puffer kann jedoch dazu führen, dass das Betriebssystem das Paket vollständig verwirft.)
– Millielch
21. Oktober 2011 um 0:03 Uhr
Wenn Sie sich Sorgen um Paketverlust und -reihenfolge machen, warum verwenden Sie UDP? Wenn Sie solche Fragen stellen, ist dies ein sehr starker Hinweis darauf, dass Sie TCP verwenden sollten
– Remus Rusanu
21. Oktober 2011 um 0:08 Uhr
Warum nicht TCP verwenden, da einige Protokolle, zB DNS, UDP-Unterstützung erfordern.
– bluejekyll
16. Februar 2016 um 15:21 Uhr
+1 Ich habe den Empfangspuffer nach einer Sekunde gelesen und da war nichts. Wenn ich es kontinuierlich mit einem nicht blockierenden rcvfrom-Aufruf lese, kann ich die Pakete lesen. Woher?
– Dunkelblick
18. März 2021 um 13:28 Uhr