¿Cuál es la solución para el reconocimiento retrasado de TCP?

He enviado un videojuego en línea (basado en la red) que utiliza el protocolo TCP para garantizar una comunicación confiable en una topología de red servidor-cliente. Mi juego funciona bastante bien, pero sufre una latencia más alta de lo esperado (los juegos TCP similares en el género parecen hacer un mejor trabajo al mantener la latencia al mínimo).

Mientras investigaba, descubrí que la latencia es inesperadamente alta para los clientes que se ejecutanMicrosoft Windows (Opuesto aMac OS X clientela). Además, descubrí que si un cliente de Windows estableceTcpAckFrequency=1 en el registro y reinicia su máquina, su latencia se vuelve normal.

Parece que el diseño de mi red no tuvo en cuenta el reconocimiento retrasado:

Un diseño que no tiene en cuenta la interacción deacuse de recibo retrasado, el algoritmo de Nagle y el almacenamiento en búfer de Winsock pueden afectar drásticamente el rendimiento. (http://support.microsoft.com/kb/214397)

Sin embargo, me resulta casi imposible tener en cuenta el reconocimiento tardío en mi juego (o en cualquier juego). Según MSDN, la pila TCP de Microsoft utiliza los siguientes criterios para decidir cuándo enviar un ACK en los paquetes de datos recibidos:

Si se recibe el segundo paquete de datos antes de que expire el temporizador de retraso (200 ms), se envía el ACK.Si hay datos para enviar en la misma dirección que el ACK antes de que se reciba el segundo paquete de datos y el temporizador de retraso expire, el ACK se complementa con el segmento de datos y se envía de inmediato.Cuando expira el temporizador de retraso (200 ms), se envía el ACK.

(http://support.microsoft.com/kb/214397)

Al leer esto, uno presumiría que la solución para el reconocimiento tardío en la pila TCP de Microsoft es la siguiente:

Deshabilite el algoritmo de Nagle (TCP_NODELAY).Deshabilite el búfer de envío del socket (SO_SNDBUF= 0), de modo que una llamada asend Se puede esperar que envíe un paquete.Cuando llamesend, si no se espera que se envíen más datos de inmediato, llame alsend nuevamente con un solo byte de datos que será descartado por el receptor.

Con este enfoque, el receptor recibirá el segundo paquete de datos aproximadamente al mismo tiempo que el paquete de datos anterior. Como resultado, elACK debe enviarse inmediatamente desde el receptor al remitente (emulando quéTcpAckFrequency=1 hace en el registro).

Sin embargo, según mis pruebas, esta latencia mejoró solo en aproximadamente la mitad de lo que hace la edición del registro. ¿Qué me estoy perdiendo?

P: ¿Por qué no usar UDP?

UNA: Elegí TCP porque cada paquete que envío debe llegar (y estar en orden); no hay paquetes que no valgan la pena retransmitir si se pierden (o se desordenan). Solo cuando los paquetes se pueden descartar / desordenar, ¡UDP puede ser más rápido que TCP!

Respuestas a la pregunta(7)

Su respuesta a la pregunta