[gull] Socket

Daniel Cordey dc at mjt.ch
Fri Sep 24 09:20:03 CEST 2004


On Friday 24 September 2004 08:52, Blaise Vogel wrote:
> En cas de
> connexion "lente" (modem/adsl), je retrouve dans le buffer 1388 bytes, puis
> 1388 bytes, puis le solde de 224 bytes ! Je dois appeler 3 fois le receive.
> En supposant un en-tête de datagramme IP de 24 bytes et un en-tête TCP de
> 24 bytes j'arrive a 1436 bytes, pas loin du mtu de l'adsl qui est de 1492.
> En résumé je ne comprends pas le comportement du receive. Que se passe-t-il
> a ce moment, la fonction ne retourne-t-elle que le(s) paquets déjà reçus ?
> Dans ce cas a quoi sert le bit de FIN de l'en tête TCP ?

Ah, ah... c'est un peu la suite de la discussion de l'autre jour a propos de 
TCP. Je conseille a tous la lecture d'un livre au sujet des protocole TCP, 
UDP, etc. 

L'utilisation du protocole garanti que vous recevrez votre "stream" de bytes 
dans l'ordre, pas que vous les recevrez d'un seul coup. En effet, le 
protocole TCP implement une notion de "pointeur" dans l'ensemble de ce qu'il 
doit recevoir. Ce pointeur (je schematise) vaut zero au debut de la connexion 
et est equivalent a ce qu'il attendait a la fin de l'ensemble des 
transactions liees au transfert. C'est a dire que ce pointeur s'incremente au 
fur et a mesure que le "destinataire" recoit des paquets et qu'il est en 
mesure de faire progresser son "bloc" de bytes recus et sans trous. Pour 
illustrer ceci, imaginons qu'un transfert de X bytes sera (pour differentes 
raisons que nous n'evoquerons pas ici) decoupe en :

A, B, C, D

Il n'y a absolument aucune garantie que ces paquets arrivent a destination 
dans le meme ordre. Imaginons donc que le destinataire recoive :

A, B, D

Le pointeur restera au niveau de la "fin" de B, et le destinataire attendra le 
bloc C pour continuer a faire avancer son "pointeur".  Il se peut aussi, que 
le bloc C (ou un autre) arrive en morceaux, soit : C1, C2, C3... de tailles 
non identiques... le "pointeur" peut quand meme "progresser".

La maniere dont le "kernel" (on devrait plutot parler des modules de gestion 
du stack IP) gere ceci est que chaque fois que le "pointeur" progresse (et 
dans un certain lapse de temps), le bout de paquet complementaire est mis a 
disposition de l'application receptrice.... Nous y voila !

C'est donc pour cette raison que l'on utilise la commande select(2), afin de 
se brancher sur un read/receive des que l'on a recu quelque chose. Notez 
aussi que select(2) est utilise pour l'ecriture lorsque les "buffers" sont 
pleins; ce qui arrive tres vite avec du pipe !

Il est d'ailleurs tres marrant de constater que cette fonction systeme est 
apparue exactement en meme temps que telnet/ftp de Berkeley. J'aurais 
tendance a dire que son besoin s'est fait sentir a ce moment :-)

dc



More information about the gull mailing list