48 votes

Comprendre le doublement de la taille de SO_SNDBUF par set/getsockopt

Bonjour, j'ai le programme suivant pour vérifier la taille du tampon d'envoi d'un socket UDP. Cependant, la valeur de retour est un peu confuse pour moi. J'utilise l'application simple suivante :

#include <sys/socket.h>
#include <stdio.h>

int main(int argc, char **argv)
{
 int sockfd, sendbuff;
 socklen_t optlen;

 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 if(sockfd == -1)
     printf("Error");

 int res = 0;

 // Get buffer size
 optlen = sizeof(sendbuff);
 res = getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);

 if(res == -1)
     printf("Error getsockopt one");
 else
     printf("send buffer size = %d\n", sendbuff);

 // Set buffer size
 sendbuff = 98304;

 printf("sets the send buffer to %d\n", sendbuff);
 res = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff));

 if(res == -1)
     printf("Error setsockopt");

 // Get buffer size
 optlen = sizeof(sendbuff);
 res = getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);

 if(res == -1)
     printf("Error getsockopt two");
 else
     printf("send buffer size = %d\n", sendbuff);

 return 0;
}

Le résultat sur ma machine est :

taille du tampon d'envoi = 129024

fixe le tampon d'envoi à 98304

nouvelle taille du tampon d'envoi = 196608

Quelqu'un peut-il clarifier ce que je fais mal ici ou comment interpréter le résultat ?

63voto

Matthew Slattery Points 21628

Tu ne fais rien de mal. Linux double la valeur (dans le noyau) lorsque vous la définissez, et renvoie la valeur doublée lorsque vous l'interrogez. man 7 socket dit :

\[...\]

    SO\_SNDBUF
              Sets or gets the maximum socket send buffer in bytes.  The  ker-
              nel doubles this value (to allow space for bookkeeping overhead)
              when it is set using setsockopt(), and  this  doubled  value  is
              returned  by  getsockopt().   The  default  value  is set by the
              wmem\_default sysctl and the maximum allowed value is set by  the
              wmem\_max sysctl.  The minimum (doubled) value for this option is
              2048.
\[...\]

NOTES
       Linux assumes that half of the send/receive buffer is used for internal
       kernel structures; thus the sysctls are twice what can be  observed  on
       the wire.
\[...\]

14 votes

Holy networking Batman ! C'est là que va tout le matériel skbuf :)

1 votes

@csyangchen : Je ne peux que deviner, mais je suppose que quelqu'un a eu l'idée qu'en définissant le tampon à la taille n, le tampon devrait être capable de contenir n octets de PAYLOAD. Une taille de tampon supplémentaire est donc nécessaire pour contenir les en-têtes de message (au moins dans le cas d'un protocole sous-jacent sans connexion, tel que UDP).

0 votes

@csyangchen J'aimerais aussi avoir plus de détails que cette vague explication. Je pense que cela pourrait être lié à la façon dont TCP fonctionne, par exemple, lorsque le tampon est de XX octets, il pourrait également y avoir la même taille d'octets en vol vers la destination. Jusqu'à ce qu'ils soient ACKed par le distant, ces octets doivent être conservés du côté de l'expéditeur, dans le pire des cas, cela pourrait être le double de ce tampon si le distant est lent à répondre et que la fenêtre TCP est plus grande que SNDBUF.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X