2010-01-08 10 views
36

Hola Tengo el siguiente programa para verificar el tamaño del búfer de envío para un socket UDP. Sin embargo, el valor de retorno es un poco confuso para mí. Yo uso la siguiente aplicación sencilla:Comprensión del conjunto/getsockopt SO_SNDBUF

#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; 
} 

La salida en mi máquina es:

envíe el tamaño del buffer = 129024

establece el buffer de envío a 98304

tamaño de búfer de envío = 196608

¿Alguien puede aclarar lo que estoy haciendo mal aquí o cómo interpretar la salida?

Respuesta

45

No está haciendo nada mal. Linux duplica el valor (dentro del kernel) cuando lo configura y devuelve el valor duplicado cuando lo consulta. man 7 socket dice:

 
[...] 

    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. 
[...] 
+9

Redes sagradas Batman! Ahí es donde van todas esas cosas skbuf :) –

+0

Me pregunto por qué el kernel dobla el valor? – csyangchen

+0

@csyangchen: Solo puedo adivinar, pero supongo que alguien tuvo la idea de que al configurar el búfer al tamaño n, el búfer debería poder contener n bytes de PAYLOAD. Por lo tanto, se necesita un tamaño de búfer adicional para mantener los encabezados de los mensajes (al menos en el caso de un protocolo subyacente sin conexión, como UDP). – Aconcagua