visual tutorial socket net example ejemplo sockets windows-phone-7 windows-phone-7.1 latency system.net

sockets - tutorial - ¿Cómo acelerar el lento/laggy Windows Phone 7(WP7) Transmisión TCP Socket?



sockets visual c++ (6)

Recientemente, comencé a usar la clase System.Net.Sockets introducida en la versión Mango de WP7 y, en general, la he estado disfrutando, pero he notado una disparidad en la latencia de la transmisión de datos en modo de depuración en comparación con el funcionamiento normal en el teléfono.

Estoy escribiendo una aplicación de "control remoto" que transmite un solo byte a un servidor local en mi LAN a través de WiFi mientras el usuario toca un botón en la aplicación. Ergo, la receptividad / puntualidad percibida de la aplicación es muy importante para una buena experiencia de usuario.

Con el teléfono conectado a mi PC a través de un cable USB y ejecutando la aplicación en modo de depuración, la conexión TCP parece transmitir paquetes tan rápido como el usuario toca los botones.

Con el teléfono desconectado de la PC, el usuario puede tocar hasta 7 botones (y por lo tanto el caso 7 envía comandos con cargas útiles de 1 byte antes de enviar los 7 bytes). Si el usuario toca un botón y espera un poco entre toques, parece haber una latencia de 1 segundo.

Intenté configurar Socket.NoDelay para True y False, y parece no hacer diferencia.

Para ver qué estaba pasando, utilicé un detector de paquetes para ver cómo era el tráfico.

  • Cuando el teléfono estaba conectado a través de USB a la PC (que estaba usando una conexión Wifi), cada byte individual estaba en su propio paquete espaciado ~ 200ms.

  • Cuando el teléfono funcionaba con su propia conexión Wifi (desconectada de USB), los bytes todavía tenían sus propios paquetes, pero estaban agrupados en ráfagas de 4 o 5 paquetes y cada grupo estaba ~ 1000ms aparte del siguiente.

Por cierto, los tiempos de Ping en mi red Wifi para el servidor son de 2 ms bajos medidos desde mi computadora portátil.

Me doy cuenta de que el almacenamiento en búfer "envía" probablemente permita que el teléfono ahorre energía, pero ¿hay alguna forma de desactivar este "retraso"? La capacidad de respuesta de la aplicación es más importante que el ahorro de energía.


Lo más probable es que no sea un problema de software. Si el teléfono usa WiFi, la demora podría ser de más de 70 ms (dependiendo de dónde esté el servidor, cuánto ancho de banda tenga, qué tan ocupado esté, la interferencia con el AP y la distancia desde el AP), pero la mayor parte del retraso es solo el WiFi. Usar GMS, CDMA, LTE o cualquier otra tecnología que el teléfono esté utilizando para datos móviles es aún más lento. No me imagino que obtendrías mucho menos de 110ms en un dispositivo celular a menos que te pusieras debajo de una torre de celular.


Parece que tus lecturas / escrituras están almacenadas en el búfer. Puede intentar establecer la propiedad NoDelay en el Socket en verdadero, también puede considerar recortar los tamaños de búfer Enviar y Recibir. La capacidad de respuesta reducida puede ser un subproducto de que no hay suficiente tráfico wifi, no estoy seguro de si el ajuste de MTU es una opción, pero la reducción de la MTU puede mejorar los tiempos de respuesta.

Todas estas son solo opciones para una solución de bajo ancho de banda, si tiene la intención de extraer megabytes de datos en cualquier dirección, querrá búferes más grandes a través de wifi, lo suficientemente grandes como para compensar la latencia de transmisión, normalmente en el rango de 32K-256K.

var socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { NoDelay = true, SendBufferSize = 3, ReceiveBufferSize = 3, };

No probé esto, pero entiendes la idea.


¿Has intentado configurar SendBufferSize = 0? En la ''C'', puede desactivar el almacenamiento en memoria intermedia de winsock estableciendo SO_SNDBUF en 0, y supongo que SendBufferSize significa lo mismo en C #


Andrew Burnett-Thompson ya lo mencionó aquí, pero también escribió que no funcionó para usted. No entiendo y no veo POR QUÉ. Entonces, déjenme explicar ese problema:

El algoritmo de Nagle se introdujo para evitar un escenario donde muchos paquetes pequeños debían enviarse a través de una red TCP. ¡Cualquier pila TCP de última generación activa el algoritmo de Nagle por defecto!

Porque: TCP en sí mismo agrega una cantidad sustancial de sobrecarga a las cosas de transferencia de datos que pasan a través de una conexión IP. Y a las aplicaciones generalmente no les importa enviar sus datos de manera optimizada sobre esas conexiones TCP. Entonces, después de todo ese algoritmo Nagle que está trabajando dentro de la pila TCP del sistema operativo, hace un trabajo muy, muy bueno.

Una mejor explicación del algoritmo de Nagle y sus antecedentes se puede encontrar en Wikipedia .

Entonces, su primer intento: desactivar el algoritmo de Nagle en su conexión TCP, configurando la opción TCP_NODELAY en el socket. ¿Eso ya resolvió tu problema? ¿Ves alguna diferencia?

Si no es así, entonces dame una señal, y profundizaremos en los detalles.

Pero, por favor, mira dos veces esas diferencias: revisa los detalles. Quizás después de todo comprendas cómo funcionan las cosas en el TCP / IP-Stack de tu sistema operativo.


¿Estabas usando Lumia 610 y mikrotik accesspoint por casualidad?

He experimentado este problema, hizo que Lumia 610 apagara la radio wifi tan pronto como se cerró la última conexión. Esta demora perceptible adicional, en comparación con Lumia 800, por ejemplo. Todas las conexiones se vieron afectadas: el solo hecho de desconectar el wifi hizo que todas las aplicaciones fueran más rápidas. Mi administrador dice que era una característica que los mikrotiks no admitían en ese momento combinado con la configuración de WMM. Extrañamente, la mayoría de los otros teléfonos estaban funcionando bien, así que culpamos de la baratura del 610 al principio.

Si aún puedes replicar el problema, te sugiero que intentes lo siguiente:

  • abra otra conexión en segundo plano y haga ping todo el tiempo.
  • use 3g / gprs en lugar de wifi (requiere exponer su servidor a internet)
  • use un teléfono diferente (o actualizado)
  • utilizar AP diferente (o actualizado)

¡Esta es una pregunta interesante! Voy a arrojar mis 2 centavos, pero tenga en cuenta que no soy un experto en System.Net.Sockets en WP7.

En primer lugar, se deben ignorar las pruebas de rendimiento mientras se está en el depurador. La razón para esto es que la sobrecarga adicional de registrar el seguimiento de la pila siempre ralentiza las aplicaciones, sin importar el SO / idioma / IDE. Las aplicaciones deben perfilarse para el rendimiento en modo de lanzamiento y desconectadas del depurador. En tu caso, ¡está realmente más lento desconectado! Ok, intentemos optimizar eso.

Si sospecha que los paquetes están siendo almacenados en búfer (y esta es una suposición razonable), ¿ha intentado enviar un paquete más grande? Pruebe aumentar linealmente el tamaño del paquete y medir la latencia. ¿Podría escribir un microperfilador simple en el código del dispositivo, es decir, utilizando DateTime.Now o la clase Stopwatch para registrar la latencia frente al tamaño del paquete? Trazar ese gráfico podría darte una buena idea de si tu teoría es correcta. Si encuentra que se envían instantáneamente paquetes de 10 bytes (o incluso 100 bytes), le sugiero que simplemente envíe más datos por transmisión. Es un truco cojo, lo sé, pero si no se rompió ...

Finalmente dices que estás usando TCP. ¿Puedes probar UDP en su lugar? TCP no está diseñado para comunicaciones en tiempo real, sino para comunicaciones precisas. El UDP por el contrario no se comprueba con errores, no se puede garantizar la entrega, pero se puede esperar un rendimiento más rápido (más ligero, con menor latencia). Las redes como Skype y los juegos en línea se basan en UDP, no en TCP. Si realmente necesita un acuse de recibo, siempre puede crear su propio micro protocolo sobre UDP, utilizando su propia Comprobación de redundancia cíclica para la verificación de errores y el protocolo Solicitud / Respuesta (acuse de recibo) .

Dichos protocolos existen, eche un vistazo al UDP confiable discutido en esta pregunta previa . Hay una implementación de RUDP basada en Java, pero estoy seguro de que algunas partes se pueden portar a C #. ¡Por supuesto, el primer paso es probar si UDP realmente ayuda!

Encontré esta pregunta previa que discute el problema. Tal vez un problema WP7? Rendimiento de UDP pobre con Windows Phone 7.1 (Mango)

Todavía estaría interesado en ver si funciona aumentar el tamaño del paquete o cambiar a UDP

Ok, ninguna sugerencia funcionó. Encontré esta descripción del algoritmo de Nagle que agrupa paquetes como usted describe. Se supone que configurar NoDelay ayuda, pero como dices, no.

http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.nodelay.aspx

También. Consulte esta pregunta previa donde Keepalive y NoDelay se activaron / desactivaron para vaciar manualmente la cola. Su evidencia es anecdótica, pero vale la pena intentarlo. ¿Puede intentarlo y editar su pregunta para publicar resultados más actualizados?

Enchufe "Flush" al habilitar temporalmente NoDelay