Effet de SO_SNDBUF

Je n’arrive pas à comprendre comment et pourquoi les segments de code suivants fonctionnent:

/* Now lets try to set the send buffer size to 5000 bytes */ size = 5000; err = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(int)); if (err != 0) { printf("Unable to set send buffer size, continuing with default size\n"); } 

Si nous vérifions la valeur du tampon d’envoi, il est en effet correctement défini à 5000 * 2 = 10000. Cependant, si nous essayons d’envoyer plus que la taille du tampon d’envoi, il l’envoie entièrement. Par exemple:

  n = send(sockfd, buf, 30000, 0); /* Lets check how much us actually sent */ printf("No. of bytes sent is %d\n", n); 

Ceci imprime 30000.

Comment cela a-t-il fonctionné? Le fait que la taille du tampon d’envoi ait été limité à 10000 n’a-t-il aucun effet? Si c’était le cas, que s’est-il passé exactement? Une sorte de fragmentation?

UPDATE: Que se passe-t-il si le socket est en mode non bloquant? J’ai essayé ce qui suit:

  1. La modification de la taille du tampon à 10 000 (5 000 * 2) entraîne l’envoi de 16 384 octets
  2. Changer la taille de la mémoire tampon à 20000 (10000 * 2) provoque l’envoi de 30000 octets

Encore une fois, pourquoi?

L’effet de la définition de l’option SO_SNDBUF est différent pour TCP et UDP.

  • Pour UDP, cela définit la limite de la taille du datagramme , c.-à-d. Que tout ce qui est plus grand sera supprimé.
  • Pour TCP, il suffit de définir la taille du tampon du kernel pour un socket donné (avec un arrondi à la limite de la page et une limite supérieure).

Comme il semble que vous parliez de TCP, l’effet que vous observez s’explique par le fait que le socket est en mode bloquant , donc send(2) blocs jusqu’à ce que le kernel puisse accepter toutes vos données et / ou la stack réseau de manière asynchrone données et de le pousser sur la carte réseau, libérant ainsi de l’espace dans le tampon.

De plus, TCP est un protocole de stream , il ne conserve aucune structure de “message”. Un send(2) peut correspondre à plusieurs recv(2) s de l’autre côté et inversement. Traitez-le comme un stream d’octets.

SO_SNDBUF configure le tampon que l’implémentation de socket utilise en interne. Si votre socket n’est pas bloquant, vous ne pouvez envoyer que la taille configurée. Si votre socket est bloqué, votre appel ne sera pas limité.