Les paquets TCP peuvent-ils arriver au destinataire par morceaux?
Par exemple, si j’envoie 20 octets en utilisant le protocole TCP, puis-je être sûr à 100% que je recevrai exactement 20 octets à la fois, et non 10 octets, puis 10 autres octets ou plus?
Et la même question pour le protocole UDP.
Je sais que UDP n'est pas fiable et que les paquets ne peuvent pas arriver du tout ou arriver dans un ordre différent, mais qu'en est-il d'un seul paquet? S'il arrive, puis-je être sûr que c'est un paquet complet, pas un morceau?
networking
tcp
udp
iamnp
la source
la source
Réponses:
Oui. IP prend en charge la fragmentation, bien que TCP tente généralement de déterminer le MTU du chemin et de garder ses paquets plus petits que cela pour des raisons de performances. La fragmentation augmente le taux de perte de datagramme de façon catastrophique. Si un chemin a un taux de perte de paquets de 10%, la fragmentation d'un datagramme en deux paquets augmente le taux de perte de datagramme à près de 20%. (Si l'un des paquets est perdu, le datagramme est perdu.)
Cependant, vous n'avez pas à vous en préoccuper, pas plus que la couche TCP. La couche IP rassemble les paquets en datagrammes entiers.
Non, mais cela n'a rien à voir avec les paquets. Le protocole TCP est fondamentalement un protocole de flux d'octets qui ne préserve pas les limites des messages d'application.
La même chose est vraie pour TCP. Les paquets sont des paquets. La différence est que TCP a des tentatives et des réordonnances intégrées au protocole, contrairement à UDP.
Non, mais ce n'est pas ton problème. Le protocole UDP gère le réassemblage du datagramme. Cela fait partie de son travail. (En réalité, le protocole IP le fait pour le protocole UDP. UDP le fait simplement en se superposant au-dessus d'IP.) Si un datagramme est divisé en deux paquets, le protocole IP le réassemblera pour le protocole UDP. verra les données complètes.
la source
Vous ne pouvez pas être sûr qu'ils arrivent vraiment physiquement à la fois. Les couches de liaison de données situées sous TCP / UDP peuvent scinder votre paquet si elles le souhaitent. Surtout si vous envoyez des données via Internet ou des réseaux indépendants de votre volonté, il est difficile de prédire cela.
Mais peu importe si les données arrivent en un ou plusieurs paquets chez le destinataire. Le système d'exploitation doit extraire la concaténation de ces paquets. Par conséquent, pour votre application, tout se passe comme si tout était arrivé en même temps. Donc, à moins que vous ne soyez un pirate du noyau, dans la plupart des cas, vous n'avez pas à vous inquiéter si ces données sont transférées dans un ou plusieurs paquets.
Pour UDP, le système d'exploitation effectue également des abstractions. Ainsi, l'application qui reçoit les données n'a pas besoin de savoir dans combien de paquets les données ont été transmises. Mais la différence avec TCP est qu’il n’ya aucune garantie que les données arrivent réellement. Il est également possible que les données soient divisées en plusieurs paquets. Certains arrivent, d'autres non. Pour l’application réceptrice, cela ressemble quand même à un flux de données, qu’elles soient complètes ou non.
la source
Exemples. Les blocs de caractères contigus correspondent aux appels send ():
TCP:
Toutes les données envoyées sont reçues dans l’ordre, mais pas nécessairement dans les mêmes morceaux.
UDP:
Les données ne sont pas nécessairement dans le même ordre et ne sont pas nécessairement reçues du tout, mais les messages sont conservés dans leur intégralité.
la source
Non, TCP est un protocole de flux, il garde les données en ordre mais ne les groupe pas par message. D'autre part, UDP est orienté message, mais peu fiable. SCTP possède le meilleur des deux mondes, mais n'est pas utilisable en mode natif, car les NAT brisent Internet.
la source
Il existe une certaine assurance que si vous envoyez 20 octets au tout début d'un flux TCP, celui-ci n'arrivera pas sous forme de deux morceaux de 10 octets. En effet, la pile TCP n'enverra pas de tels segments: il existe une taille minimale de MTU. Cependant, si l'envoi se trouve n'importe où au milieu d'un flux, tous les paris sont désactivés. Il se peut que votre pile de protocoles utilise 10 octets de données pour remplir un segment et l'envoyer, puis que les dix octets suivants passent à un autre segment.
Votre pile de protocoles divise les données en fragments et les place dans une file d'attente. Les tailles de bloc sont basées sur le MTU du chemin. Si vous effectuez une opération d'envoi et que des données sont toujours en attente, la pile de protocoles examine généralement le segment situé à la fin de la file d'attente et voit s'il y a suffisamment d'espace dans ce segment pour ajouter des données. La pièce peut être aussi petite qu'un octet, de sorte que même un envoi sur deux octets peut être divisé en deux.
Par ailleurs, la segmentation des données signifie qu'il peut y avoir des lectures partielles. Une opération de réception peut potentiellement se réveiller et obtenir des données lorsqu'un seul segment arrive. Dans l’API des sockets largement implémentée, un appel reçu peut demander 20 octets, mais il peut en renvoyer 10. Bien entendu, il est possible de construire une couche de mise en mémoire tampon qui bloque jusqu’à ce que 20 octets soient reçus ou que la connexion soit interrompue. Dans le monde POSIX, cette API peut être le flux d’entrée / sortie standard: vous pouvez utiliser
fdopen
un descripteur de socket pour obtenir unFILE *
flux et l’utiliserfread
pour remplir un tampon de sorte que la demande complète soit satisfaite avec autant d’read
appels qu’elle prend. .Les datagrammes UDP encadrent les données. Chaque appel envoyé génère un datagramme (mais voir ci-dessous à propos du bouchage). L'autre côté reçoit un datagramme complet (et, dans l'API de socket, il doit spécifier un tampon suffisamment grand pour le contenir, sinon le datagramme sera tronqué). Les grands datagrammes sont fragmentés par fragmentation IP et sont réassemblés de manière transparente pour les applications. Si un fragment est manquant, le datagramme entier est perdu; il n'y a aucun moyen de lire des données partielles dans cette situation.
Il existe des extensions à l'interface permettant à plusieurs opérations de spécifier un seul datagramme. Sous Linux, une socket peut être "bouchée" (envoi interdit). Bien qu’il soit bouché, les données écrites sont assemblées en une seule unité. Ensuite, lorsque la socket est "débouchée", un seul datagramme peut être envoyé.
la source