Il existe une certaine assurance que si vous envoyez 20 octets au tout début d'un flux TCP, cela n'arrivera pas en deux morceaux de 10 octets chacun. C'est parce que la pile TCP ne renverra pas de si petits segments : il y a une taille MTU minimale. Cependant, si l'envoi se fait n'importe où dans le milieu d'un flux, tout est possible. Il se peut que votre pile de protocole prenne 10 octets de données pour remplir un segment et l'envoyer, puis que les dix octets suivants aillent dans un autre segment.
Votre pile de protocole divise les données en morceaux et les place dans une file d'attente. Les tailles des morceaux sont basées sur la MTU du chemin. Si vous effectuez une opération d'envoi et qu'il y a encore des données en attente dans la file d'attente, la pile de protocole va généralement jeter un œil au segment qui se trouve à la fin de la file d'attente pour voir s'il y a de la place dans ce segment pour ajouter plus de données. La place peut être aussi petite qu'un octet, donc même un envoi de deux octets peut être divisé en deux.
D'autre part, 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 dès qu'un seul segment arrive. Dans l'API de sockets largement mise en œuvre, un appel de réception peut demander 20 octets, mais il pourrait retourner avec 10. Bien sûr, une couche tampon peut être construite dessus, qui bloquera jusqu'à ce que 20 octets soient reçus, ou que la connexion soit interrompue. Dans le monde POSIX, cette API peut être les flux d'E/S standard : vous pouvez fdopen
un descripteur de socket pour obtenir un flux FILE *
et vous pouvez utiliser fread
dessus pour remplir un tampon de telle sorte que la requête complète soit satisfaite avec autant d'appels read
que nécessaire.
Les datagrammes UDP encadrent les données. Chaque appel d'envoi génère un datagramme (mais voir ci-dessous au sujet de corking). L'autre côté reçoit un datagramme complet (et, dans l'API de socket, il doit spécifier un tampon assez grand pour le contenir, sinon le datagramme sera tronqué). Les grands datagrammes sont fragmentés par la fragmentation IP, et sont ré-assemblés de manière transparente pour les applications. Si un fragment manque, 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, un socket peut être "corked" (empêché d'envoyer). Pendant qu'il est "corked", les données écrites sont assemblées en une seule unité. Ensuite, lorsque le socket est "uncorked", un seul datagramme peut être envoyé.