windows - socket - winsock2 0
Qué son SO_SNDBUF y SO_RECVBUF (3)
¿Puede explicarme qué son exactamente las opciones SO_SNDBUF
y SO_RECVBUF
?
OK, por alguna razón, el sistema operativo almacena temporalmente los datos salientes / entrantes, pero me gustaría aclarar este tema.
¿Cuál es su función (generalmente)?
¿Son buffers por socket?
¿Hay una conexión entre los búferes de la capa de transporte (el búfer TCP, por ejemplo) y estos búferes?
¿Tienen un comportamiento / rol diferente cuando usan sockets de flujo (TCP) y cuando usan sockets sin conexión (UDP)?
Un buen artículo será genial también.
Busqué en Google pero no encontré ninguna información útil.
Buscando en Google "SO_RECVBUF msdn" me dio ...
http://msdn.microsoft.com/en-us/library/ms740476(VS.85).aspx
que responde a su "son ellos por socket" con estas líneas de la tabla de opciones:
SO_RCVBUF int Specifies the total per-socket buffer space reserved for receives.
SO_SNDBUF int Specifies the total per-socket buffer space reserved for sends.
Con más detalle más adelante:
SO_RCVBUF y SO_SNDBUF
Cuando una implementación de Windows Sockets admite las opciones SO_RCVBUF y SO_SNDBUF, una aplicación puede solicitar diferentes tamaños de búfer (más grandes o más pequeños). La llamada a setsockopt puede tener éxito incluso cuando la implementación no proporcionó la cantidad total solicitada. Una aplicación debe llamar a getsockopt con la misma opción para verificar el tamaño del búfer realmente provisto.
El prefijo "SO_" es para "opción de socket", así que sí, estos son ajustes por socket para los búferes por socket. Generalmente hay valores predeterminados y valores máximos para todo el sistema.
SO_RCVBUF
es más fácil de entender: es el tamaño del búfer que el kernel asigna para mantener los datos que llegan al socket dado durante el tiempo que transcurre entre la red y cuando el programa que posee este socket lo lee. Con TCP, si llegan datos y usted no los está leyendo, el búfer se llenará y se le indicará al remitente que reduzca la velocidad (utilizando el mecanismo de ajuste de la ventana TCP). Para UDP, una vez que el buffer está lleno, los paquetes nuevos simplemente serán descartados.
SO_SNDBUF
, creo, solo importa para TCP (en UDP, lo que sea que envíe va directamente a la red). Para TCP, puede llenar el búfer si el lado remoto no está leyendo (para que el búfer remoto se llene, entonces TCP comunica este hecho a su kernel, y su núcleo deja de enviar datos, en su lugar, lo acumula en el búfer local hasta que llena). O podría llenarse si hay un problema de red, y el kernel no recibe reconocimientos por los datos que envía. A continuación, disminuirá el envío de datos en la red hasta que, finalmente, se llene el búfer de salida. Si es así, las llamadas futuras de write()
a este socket por parte de la aplicación bloquearán (o devolverán EAGAIN
si usted configuró la opción O_NONBLOCK
).
Todo esto se describe mejor en el libro de Programación de Red Unix .
En Windows, el búfer de envío tiene un efecto en UDP. Si lanza los paquetes más rápido de lo que la red puede transmitirlos, eventualmente llenará el buffer de salida del socket y SendTo fallará con "would block". Aumentar SO_SNDBUF ayudará con esto. Tuve que aumentar los búferes de envío y recepción de una prueba que estaba haciendo para encontrar la máxima tasa de paquetes que podía enviar entre una caja de Windows y una de Linux. También podría haber manejado el tamaño de envío al detectar el código de error "bloquearía", dormir un poco y volver a intentarlo. Pero aumentar el tamaño del búfer de envío fue más simple. El valor predeterminado en Windows es 8K, que parece innecesariamente pequeño en esta era de PC con GB de RAM.