it-swarm.com.de

Können TCP und UDP-Pakete in Teile geteilt werden?

Können TCP Pakete stückweise beim Empfänger ankommen?

Wenn ich beispielsweise 20 Bytes mit dem Protokoll TCP Protokoll) sende, kann ich dann 100% sicher sein, dass ich genau 20 Bytes auf einmal empfange, nicht 10 Bytes, sondern weitere 10 Bytes oder so?

Und die gleiche Frage für das UDP-Protokoll.
Ich weiß, dass UDP unzuverlässig ist und Pakete überhaupt nicht oder in unterschiedlicher Reihenfolge ankommen können, aber was ist mit einem einzelnen Paket? Kann ich bei Eintreffen sicher sein, dass es sich um ein vollständiges Paket handelt, nicht um ein Stück?

41
iamnp

können TCP Pakete stückweise beim Empfänger ankommen?

Ja. IP unterstützt die Fragmentierung, obwohl TCP versucht im Allgemeinen, die Pfad-MTU zu bestimmen und ihre Pakete aus Leistungsgründen kleiner als diese zu halten. Die Fragmentierung erhöht die Datagramm-Verlustrate katastrophal. Wenn ein Pfad einen Paketverlust von 10% aufweist Wenn Sie ein Datagramm in zwei Pakete fragmentieren, beträgt die Datagramm-Verlustrate fast 20%. (Wenn eines der Pakete verloren geht, geht das Datagramm verloren.)

Sie müssen sich darüber jedoch keine Gedanken machen, und die TCP -Schicht. Die IP-Schicht setzt Pakete zu ganzen Datagrammen zusammen.

Zum Beispiel: Wenn ich 20 Bytes mit dem Protokoll TCP Protokoll) sende, kann ich dann 100% sicher sein, dass ich genau 20 Bytes auf einmal empfange, nicht 10 Bytes, sondern weitere 10 Bytes oder so?

Nein, aber das hat nichts mit Paketen zu tun. TCP ist im Grunde ein Byte-Stream-Protokoll, bei dem die Grenzen der Anwendungsnachrichten nicht beibehalten werden.

Und die gleiche Frage für das UDP-Protokoll. Ich weiß, dass UDP unzuverlässig ist und Pakete überhaupt nicht oder in unterschiedlicher Reihenfolge ankommen können.

Gleiches gilt für TCP. Pakete sind Pakete. Der Unterschied besteht darin, dass TCP hat Wiederholungsversuche und Neuordnungen in das Protokoll integriert, während UDP dies nicht tut.

aber was ist mit 1 Paket? Kann ich bei Eintreffen sicher sein, dass es sich um ein vollständiges Paket handelt, nicht um ein Stück?

Nein, aber das ist nicht dein Problem. Das UDP-Protokoll übernimmt das Zusammensetzen von Datagrammen. Das gehört zu seiner Arbeit. (Tatsächlich erledigt das IP-Protokoll dies für das UDP-Protokoll, also tut UDP dies lediglich, indem es über IP geschichtet wird.) Wenn ein Datagramm auf zwei Pakete aufgeteilt wird, setzt das IP-Protokoll es für das UDP-Protokoll wieder zusammen, so dass Sie wird die vollständigen Daten sehen.

33
David Schwartz

Sie können nicht sicher sein, dass sie wirklich sofort physisch ankommen. Die Datenverbindungsschichten unter TCP/UDP können Ihr Paket aufteilen, wenn sie möchten. Insbesondere wenn Sie Daten über das Internet oder Netzwerke außerhalb Ihrer Kontrolle senden, ist dies schwer vorherzusagen.

Aber egal ob die Daten in einem Paket oder in mehreren Paketen beim Empfänger ankommen. Das Betriebssystem sollte die Verkettung dieser Pakete abstrahieren, sodass für Ihre Anwendung immer noch alles auf einmal eingetroffen ist. Wenn Sie also kein Kernel-Hacker sind, müssen Sie sich in den meisten Fällen keine Sorgen machen, wenn diese Daten in einem oder mehreren Paketen übertragen werden.

Für UDP führt das Betriebssystem auch eine gewisse Abstraktion durch, sodass die Anwendung, die die Daten empfängt, nicht wissen muss, in wie vielen Paketen die Daten übertragen wurden. Der Unterschied zu TCP) besteht jedoch darin, dass es keine Garantie dafür gibt, dass die Daten tatsächlich ankommen. Es ist auch möglich, dass die Daten in mehrere Pakete aufgeteilt werden und einige von ihnen ankommen und andere nicht Für die empfangende Anwendung sieht es sowieso nur wie ein Datenstrom aus, egal ob er vollständig ist oder nicht.

20
replay

Beispiele. Blöcke zusammenhängender Zeichen entsprechen send () -Aufrufen:

TCP:

Send: AA BBBB CCC DDDDDD E         Recv: A ABB B BCC CDDD DDDE

Alle gesendeten Daten werden in der richtigen Reihenfolge empfangen, jedoch nicht unbedingt in denselben Blöcken.

UDP:

Send: AA BBBB CCC DDDDDD E         Recv: CCC AA E

Die Daten befinden sich nicht unbedingt in derselben Reihenfolge und werden überhaupt nicht empfangen, aber die Nachrichten bleiben in ihrer Gesamtheit erhalten.

14
Jim Cote

Zum Beispiel: Wenn ich 20 Bytes mit dem Protokoll TCP Protokoll) sende, kann ich dann 100% sicher sein, dass ich genau 20 Bytes auf einmal empfange, nicht 10 Bytes, sondern weitere 10 Bytes oder so?

Nein, TCP ist ein Stream-Protokoll, hält die Daten in Ordnung, gruppiert sie jedoch nicht nach Nachrichten. Andererseits ist UDP nachrichtenorientiert, aber unzuverlässig. SCTP hat das Beste aus beiden Welten, ist aber nicht nativ verwendbar, da NATs das Internet beschädigen.

5
Changaco

Es besteht die Gewissheit, dass wenn Sie 20 Bytes ganz am Anfang eines TCP - Streams senden), diese nicht als zwei 10-Byte-Teile ankommen. Dies liegt daran, dass TCP = Stack sendet keine so kleinen Segmente: Es gibt eine minimale MTU-Größe. Wenn sich der Send jedoch irgendwo in der Mitte eines Streams befindet, sind alle Wetten deaktiviert. Es kann sein, dass Ihr Protokollstack 10 Byte der zu füllenden Daten benötigt ein Segment und senden Sie es aus, und dann gehen die nächsten zehn Bytes zu einem anderen Segment.

Ihr Protokollstapel zerlegt Daten in Blöcke und stellt sie in eine Warteschlange. Die Blockgrößen basieren auf dem Pfad MTU. Wenn Sie einen Sendevorgang ausführen und noch Daten in der Warteschlange stehen, schaut der Protokollstapel normalerweise auf das Segment am Ende der Warteschlange und prüft, ob in diesem Segment Platz zum Hinzufügen weiterer Daten vorhanden ist. Der Raum kann so klein wie ein Byte sein, sodass sogar ein Zwei-Byte-Sendevorgang in zwei Teile aufgeteilt werden kann.

Andererseits bedeutet die Segmentierung von Daten, dass es teilweise Lesevorgänge geben kann. Eine Empfangsoperation kann möglicherweise aufwachen und Daten abrufen, wenn nur ein Segment eintrifft. In der weit verbreiteten Sockets-API kann ein Empfangsaufruf 20 Bytes anfordern, aber mit 10 zurückkehren. Natürlich kann darauf eine Pufferschicht aufgebaut werden, die blockiert, bis 20 Bytes empfangen werden oder die Verbindung unterbrochen wird. In der POSIX-Welt kann diese API die Standard-E/A-Streams sein: Sie können fdopen einen Socket-Deskriptor verwenden, um ein FILE * stream, und Sie können fread verwenden, um einen Puffer so zu füllen, dass die vollständige Anforderung mit so vielen read -Aufrufen erfüllt wird, wie erforderlich sind.

UDP-Datagramme rahmen die Daten ein. Jeder Sendeanruf generiert ein Datagramm (siehe unten zum Verkorken). Die andere Seite empfängt ein vollständiges Datagramm (und muss in der Socket-API einen Puffer angeben, der groß genug ist, um es aufzunehmen, sonst wird das Datagramm abgeschnitten). Große Datagramme werden durch IP-Fragmentierung fragmentiert und für Anwendungen transparent neu zusammengestellt. Wenn ein Fragment fehlt, geht das gesamte Datagramm verloren. In dieser Situation gibt es keine Möglichkeit, Teildaten zu lesen.

Es gibt Erweiterungen für die Schnittstelle, mit denen mehrere Vorgänge ein einzelnes Datagramm angeben können. Unter Linux kann ein Socket "verkorkt" werden (am Senden gehindert). Während es verkorkt ist, werden geschriebene Daten zu einer Einheit zusammengefasst. Wenn der Socket dann "entkorkt" ist, kann ein einzelnes Datagramm gesendet werden.

1
Kaz