Wie lange bleibt ein UDP-Paket an einem Socket?

Lesezeit: 6 Minuten

Benutzer-Avatar
TTT

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)

  • 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

Benutzer-Avatar
Damon

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 recvfroma 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.

  • “Sie wissen einfach nicht, dass etwas passiert ist” ist nicht ganz richtig, auf einigen Stacks gibt es Statistiken über Pakete, die aufgrund fehlender Fragmente, ungültiger Prüfsummen, unzureichendem Pufferspeicher usw. verworfen wurden. Aber es ist wahr, dass Sie nie Teilpakete mit geliefert bekommen der übliche Mechanismus.

    – Ben Voigt

    13. Februar 2016 um 16:55 Uhr

  • Aber das ist nicht wahr. Ich habe Pakete an einen Socket gesendet und den Socket nach einer Sekunde gelesen, und da war nichts. Wenn ich es aktiv (rcvfrom) in einer Schleife mit nicht blockierenden Aufrufen auslese, bekomme ich Pakete. Wie kommt es dazu?

    – Dunkelblick

    18. März 2021 um 13:27 Uhr

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.

  • Es füllt hauptsächlich den Socket-Puffer, nicht (nur) den Treiber. Es bleibt im Socket-Puffer, bis Sie es lesen oder der Prozess beendet wird. Sobald der Socket-Puffer voll ist, werden neu ankommende Pakete verworfen.

    – Nr

    21. Oktober 2011 um 0:25 Uhr


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.

  • Die Daten werden stets bleibe, sobald es akzeptiert wurde; Wenn jedoch bereits zu viele alte Daten gepuffert sind, werden neue Daten verworfen.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    21. Oktober 2011 um 2:09 Uhr

  • Was passiert mit Paketen aus anderen Quellen als denen, die ich recv_from? Überschwemmen sie nur den Betriebssystempuffer?

    – Aleš Koblížek

    15. Juni 2015 um 9:24 Uhr

  • @AlešKoblížek: recvfrom gibt nicht an, von welchem ​​Absender Daten akzeptiert werden sollen, sondern lässt Ihr Programm die Adresse des Absenders herausfinden (der Adressparameter ist eine Ausgabe, keine Eingabe). Es gibt also keine “anderen Quellen als die, aus denen ich empfange”. recvfrom erhält Daten aus allen Quellen.

    – Ben Voigt

    13. Februar 2016 um 16:52 Uhr


1176450cookie-checkWie lange bleibt ein UDP-Paket an einem Socket?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy