Problema con retrasos en los paquetes en el adaptador de bucleback TCP/IP Windows 7 (¿o error en el software?)

StackOverflow https://stackoverflow.com/questions/5321542

Pregunta

Tenemos una aplicación de cliente y servidor que actualmente prueba en la misma máquina Windows 7 de 64 bits. Ambos están escritos en C# y usando P/Invoke para llamar a las bibliotecas Winsock2.

La aplicación funciona bien en general sin ningún error. Y la latencia para cada "salto" sobre TCP/IP promedia aproximadamente 350 microsegundos.

Sin embargo, en ocasiones hay retrasos muy largos de más de 40 a 50 ms antes de recibir paquetes y de repente llegarán todos.

Esfuerzos para diagnosticar hasta ahora:

  1. Durante estos retrasos que reciben datos, el servidor continúa registrando que está enviando paquetes. Está configurado para enviar paquetes de prueba cada 1 ms que hará durante 15 o 20 y hasta 50 ms a veces antes de que el cliente reciba alguno de ellos.

  2. El TCPDUMP se usó para olfatear paquetes en el adaptador de bucle y muestra que durante este período de retraso, hay tráfico desde el puerto del servidor (6488) al puerto del cliente (61743) como de costumbre.

  3. El cliente llama a la llamada select () winsock2 en un bucle, por lo que el registro a través de un contador antes de la llamada select () muestra que tiene el descriptor de archivo correcto. Y, por supuesto, esto funciona antes y después del retraso bien.

  4. El registro adicional inmediatamente después de la llamada Select () muestra que el FD no está presente, lo que significa que una lectura en el socket bloqueará. Sin embargo, durante los períodos de transmisión sin retrasos, el registro muestra que funciona como se esperaba para que select () devuelva el FD del enchufe para hacer una lectura sin bloqueo.

En resumen, el adaptador de loopback parece contener estos paquetes en algún lugar durante mucho tiempo antes de finalmente entregarlos al lado receptor.

¿Hay más ideas o una solución?

Algunos pensamientos son a menudo se afirman que la E/S superpuesta funciona mejor en Windows, pero eso parece importar solo para la escalabilidad si necesita escuchar más de 64 enchufes.

¿Puede ser que cambiar a superpuesto hará el truco? Queremos evitar, ya que eso aumentará la fecha límite y el presupuesto del proyecto. Esto debería funcionar con select () muy bien.

Además, ¿puede ser que el proceso o el hilo en Windows que maneja el bucleback se cambie el contexto o algo así y, de ser así, hay alguna forma de configurarlo para evitar esos retrasos?

EDITAR: La respuesta correcta fue asegurarse de que el algoritmo Nagle estuviera deshabilitado. Pensamos que estaba deshabilitado, pero ahí es donde se encontró el error, en nuestra implementación interna de setSocketOption () que utilizamos GetSocketOption () para verificar. Por lo tanto, resulta que debe establecer Nodelay antes de conectar o unir un socket o de lo contrario no tiene ningún efecto.

¡Muchas gracias a Fun Mun Pieng por la respuesta correcta!

¿Fue útil?

Solución

Sospecho que esto puede deberse al Algoritmo de nagle. El siguiente código lo deshabilita:

socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top