sol_socket c sockets udp datagram setsockopt

sol_socket



¿Hay alguna manera de reducir el límite inferior mínimo del tamaño del búfer de envío del zócalo? (1)

Estoy tratando de cambiar el tamaño del búfer de envío de socket predeterminado a un tamaño pequeño, para ver cómo se ve afectado el rendimiento de UDP para pequeños datagramas UDP. Para hacer esto, utilizo la función setsockopt con la opción SO_SNDBUF y estoy tratando de establecer el tamaño del búfer en 64 bytes. También uso getsockopt para ver el resultado de la función setsockopt .

Aquí está el código que uso:

int sock_fd; struct sockaddr_in server_addr; static int target_port = PORT; int curr_snd_buff = 0; int sk_snd_buff = 64; socklen_t optlen; if( (sock_fd=socket(AF_INET,SOCK_DGRAM,0)) == -1) fatal("in socket (client_udp)"); memset(&server_addr, 0, sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr=inet_addr(args->a_ip); server_addr.sin_port=htons(target_port); if ( sk_snd_buff > 0 ) >{ optlen = sizeof(sk_snd_buff); // get the default socketh send buffer size if (getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &curr_snd_buff, &optlen) == -1) { fatal("getting the socket send buffer"); } printf("* default socket send buffer: %d/n", curr_snd_buff); printf("* attempting to change it to: %d/n", sk_snd_buff); if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &sk_snd_buff, optlen) == -1) { fatal("changing the socket send buffer"); } if (getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &curr_snd_buff, &optlen) == -1) { fatal("getting the socket send buffer"); } printf("* new socket send buffer: %d/n", curr_snd_buff); }

Pero, lo que veo es que hay un límite inferior del tamaño del búfer establecido en 4608 bytes cada vez que intento establecer un valor pequeño. Aquí está el resultado del código anterior:

  • Buffer de envío de socket predeterminado: 212992
  • intentando cambiarlo a: 2304
  • nuevo búfer de envío de socket: 4608

Al probar varios tamaños, descubrí que esto sucede para tamaños <= 2304. Para tamaños más grandes, p. Ej. 2305, obtengo un tamaño mayor:

  • Buffer de envío de socket predeterminado: 212992
  • intentando cambiarlo a: 2305
  • nuevo búfer de envío de socket: 4610

y para algunos tamaños más grandes, por ejemplo, 3000, el doble del tamaño que he solicitado:

  • Buffer de envío de socket predeterminado: 212992
  • intentando cambiarlo a: 3000
  • nuevo búfer de envío de socket: 6000

Al buscar en la red encontré que Linux duplica el valor dentro del núcleo cuando lo configura, y devuelve el valor duplicado cuando lo consulta: Comprender set / getsockopt SO_SNDBUF

¿Hay alguna manera de reducir el límite inferior mínimo del tamaño del búfer de envío del zócalo? Por ejemplo, para establecerlo en 64 bytes?


El tamaño mínimo de búfer es una función del kernel. Los documentos de Linux para la opción SO_SNDBUF tienen esto que decir:

Establece u obtiene el búfer de envío de socket máximo en bytes. El kernel dobla este valor (para permitir espacio para gastos generales de contabilidad) cuando se establece usando setsockopt (2), y este valor duplicado es devuelto por getsockopt (2). El valor predeterminado se establece mediante el archivo / proc / sys / net / core / wmem_default y el valor máximo permitido se establece mediante el archivo / proc / sys / net / core / wmem_max. El valor mínimo (duplicado) para esta opción es 2048.

(página de manual de socket (7))

Los detalles probablemente variarán en los diferentes sistemas, pero

  1. Eso explica el doblez que ves: la capacidad del búfer para los bytes salientes es el tamaño que estableces, pero el kernel se reserva e informa el doble del espacio total.
  2. En Linux, al menos, no podrá establecer un búfer tan pequeño como diga que quiere. Supongo que otros sistemas tendrían restricciones del mismo orden de magnitud.