Es una optimización, como cualquier optimización:
- No lo use
- Espere hasta que el rendimiento se convierta en un problema, luego de haber determinado que la latencia del socket es definitivamente la causa del problema, y las pruebas demuestran que esto definitivamente lo solucionará, Y esta es la forma más fácil de solucionarlo, hágalo.
Básicamente, el objetivo es evitar tener que enviar varios marcos donde se puede usar un solo marco, con sendfile() y sus amigos.
Entonces, por ejemplo, en un servidor web, envía los encabezados seguidos del contenido del archivo, los encabezados se ensamblarán en la memoria y el kernel enviará el archivo directamente. TCP_CORK le permite enviar los encabezados y el comienzo del archivo en un solo marco, incluso con TCP_NODELAY, que de lo contrario haría que el primer fragmento se enviara de inmediato.
TCP_NODELAY
Se usa para deshabilitar el algoritmo de Nagle para mejorar las redes TCP/IP y disminuir la cantidad de paquetes al esperar hasta que se reciba un reconocimiento de los datos enviados previamente para enviar los paquetes acumulados.
//Del manual de tcp(7):
TCP_CORK
(o TCP_NOPUSH
en FreeBSD)
Si está configurado, no envíe marcos parciales. Todos los marcos parciales en cola se envían cuando la opción se borra nuevamente. Esto es útil para anteponer encabezados antes de llamar a sendfile(2)
o para la optimización del rendimiento. Tal como se implementa actualmente, hay un límite de 200 milisegundos en el tiempo durante el cual la salida está tapada por TCP_CORK
. Si se alcanza este límite, los datos en cola se transmiten automáticamente . Esta opción se puede combinar con TCP_NODELAY
solo desde Linux 2.5.71. Esta opción no debe usarse en código destinado a ser portátil.
En primer lugar, ninguno de los dos desactiva el algoritmo de Nagle.
El algoritmo de Nagle es para reducir una mayor cantidad de pequeños paquetes de red en el cable. El algoritmo es:si los datos son más pequeños que un límite (generalmente MSS), espere hasta recibir ACK para los paquetes enviados previamente y, mientras tanto, acumule datos del usuario. Luego envía los datos acumulados.
if [ data > MSS ]
send(data)
else
wait until ACK for previously sent data and accumulate data in send buffer (data)
And after receiving the ACK send(data)
Esto ayudará en aplicaciones como telnet. Sin embargo, esperar el ACK puede aumentar la latencia al enviar datos de transmisión. Además, si el receptor implementa la 'política de ACK retrasado', provocará una situación de interbloqueo temporal. En tales casos, deshabilitar el algoritmo de Nagle es una mejor opción.
Entonces TCP_NODELAY se usa para deshabilitar el algoritmo de Nagle.
TCP_CORK acumula datos de forma agresiva. Si TCP_CORK está habilitado en un socket, no enviará datos hasta que el búfer se llene hasta un límite fijo. Similar al algoritmo de Nagle, también acumula datos del usuario, pero hasta que el búfer se llena hasta un límite fijo, no hasta que recibe ACK. Esto será útil al enviar múltiples bloques de datos. Pero debe tener más cuidado al usar TCP_CORK.
Hasta el kernel 2.6, ambas opciones son mutuamente excluyentes. Pero en kernel posterior, ambos pueden existir juntos. En tal caso, se dará más preferencia a TCP_CORK.
Referencia:
- http://baus.net/on-tcp_cork/
- http://ccr.sigcomm.org/archive/2001/jan01/ccr-200101-mogul.pdf