Können TCP-Pakete stückweise beim Empfänger ankommen?
Wenn ich zum Beispiel 20 Bytes mit dem TCP-Protokoll sende, kann ich dann zu 100% sicher sein, dass ich genau 20 Bytes auf einmal erhalte, nicht 10 Bytes, sondern weitere 10 Bytes oder so?
Und die gleiche Frage für 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? Wenn es eintrifft, kann ich sicher sein, dass es sich um ein vollständiges Paket handelt, nicht um ein Teil?
networking
tcp
udp
iamnp
quelle
quelle
Antworten:
Ja. IP unterstützt die Fragmentierung, obwohl TCP im Allgemeinen versucht, die Pfad-MTU zu ermitteln und die Pakete aus Leistungsgründen kleiner als diese zu halten. Die Fragmentierung erhöht die Datenverlustrate katastrophal. Wenn ein Pfad eine Paketverlustrate von 10% aufweist, führt die Fragmentierung eines Datagramms in zwei Pakete zu einer fast 20% igen Datenverlustrate. (Wenn eines der Pakete verloren geht, geht das Datagramm verloren.)
Darüber müssen Sie sich jedoch keine Gedanken machen und die TCP-Schicht auch nicht. Die IP-Schicht setzt Pakete wieder zu ganzen Datagrammen zusammen.
Nein, aber das hat nichts mit Paketen zu tun. TCP ist im Grunde genommen ein Byte-Stream-Protokoll, bei dem die Grenzen von Anwendungsnachrichten nicht beibehalten werden.
Gleiches gilt für TCP. Pakete sind Pakete. Der Unterschied besteht darin, dass TCP Wiederholungsversuche und Neuanordnungen in das Protokoll integriert hat, UDP jedoch nicht.
Nein, aber das ist nicht dein Problem. Das UDP-Protokoll übernimmt das erneute Zusammensetzen von Datagrammen. Das ist ein Teil seiner Arbeit. (Tatsächlich erledigt das IP-Protokoll dies für das UDP-Protokoll. UDP erledigt dies also nur, indem es über IP gelegt 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.
quelle
Sie können nicht sicher sein, dass sie wirklich physisch sofort ankommen. Die Datenverbindungsschichten unter TCP / UDP können Ihr Paket aufteilen, wenn sie dies möchten. Insbesondere wenn Sie Daten über das Internet oder ein Netzwerk senden, auf das Sie keinen Einfluss haben, 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 es für Ihre Anwendung immer noch so aussieht, als wäre alles auf einmal angekommen. 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 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 eintreffen. Es ist auch möglich, dass die Daten in mehrere Pakete aufgeteilt werden, von denen einige eintreffen und andere nicht. Für die empfangende Anwendung sieht es sowieso nur aus wie ein Datenstrom, egal ob er vollständig ist oder nicht.
quelle
Beispiele. Blöcke von zusammenhängenden Zeichen entsprechen send () -Aufrufen:
TCP:
Alle gesendeten Daten werden in der richtigen Reihenfolge empfangen, jedoch nicht unbedingt in denselben Blöcken.
UDP:
Die Daten müssen nicht unbedingt in der gleichen Reihenfolge vorliegen und überhaupt nicht empfangen werden, aber die Nachrichten bleiben in ihrer Gesamtheit erhalten.
quelle
Nein, TCP ist ein Stream-Protokoll. Es hält die Daten in der richtigen Reihenfolge, gruppiert sie jedoch nicht nach Nachrichten. Auf der anderen Seite ist UDP nachrichtenorientiert, aber unzuverlässig. SCTP bietet das Beste aus beiden Welten, ist jedoch nicht nativ verwendbar, da NATs das Internet beschädigen.
quelle
Es besteht die Gewissheit, dass beim Senden von 20 Bytes am Anfang eines TCP-Streams keine zwei 10-Byte-Teile eingehen. Dies liegt daran, dass der TCP-Stack keine so kleinen Segmente sendet: Es gibt eine minimale MTU-Größe. Befindet sich der Send jedoch irgendwo in der Mitte eines Streams, sind alle Wetten deaktiviert. Es kann sein, dass Ihr Protokollstapel 10 Byte der Daten benötigt, um ein Segment zu füllen und auszusenden, und dann die nächsten 10 Byte in ein anderes Segment gehen.
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 anstehen, wird der Protokollstapel in der Regel das Segment am Ende der Warteschlange überprüfen und feststellen, ob in diesem Segment Platz zum Hinzufügen weiterer Daten vorhanden ist. Der Raum kann so klein wie ein Byte sein, so dass sogar ein Zwei-Byte-Send in zwei Teile aufgeteilt werden kann.
Am anderen Ende bedeutet die Segmentierung von Daten, dass es teilweise Lesevorgänge geben kann. Eine Empfangsoperation kann möglicherweise aktiviert werden und Daten abrufen, wenn nur ein Segment eintrifft. In der weit verbreiteten Sockets-API kann ein Empfangsaufruf nach 20 Bytes fragen, er kann jedoch mit 10 zurückkehren. Natürlich kann eine Pufferschicht darauf 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-Datenströme sein: Sie können
fdopen
einen Socket-Deskriptor zum Abrufen einesFILE *
Datenstroms verwenden,fread
um einen Puffer so zu füllen, dass die vollständige Anforderung mit so vielenread
Aufrufen wie nötig erfüllt wird .UDP-Datagramme rahmen die Daten ein. Jeder Sendeaufruf generiert ein Datagramm (siehe unten zum Verkorken). Die andere Seite empfängt ein vollständiges Datagramm (und in der Socket-API muss ein Puffer angegeben werden, der groß genug ist, um es aufzunehmen, da das Datagramm sonst abgeschnitten wird). 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 können keine Teildaten gelesen werden.
Es gibt Erweiterungen für die Schnittstelle, mit denen mehrere Operationen ein einzelnes Datagramm angeben können. Unter Linux kann ein Socket "verkorkt" werden (das Senden wird verhindert). Während des Verkorkens werden geschriebene Daten zu einer Einheit zusammengefasst. Wenn der Socket dann "entkorkt" ist, kann ein einzelnes Datagramm gesendet werden.
quelle