¿El protocolo TCP es lo suficientemente bueno para los juegos multijugador en tiempo real?


57

En el pasado, las conexiones TCP a través de acceso telefónico / ISDN / banda ancha lenta resultaron en juegos entrecortados y rezagados debido a que un solo paquete descartado resultó en una resincronización. Eso significaba que muchos desarrolladores de juegos tenían que implementar su propia capa de confiabilidad además de UDP, o usaban UDP para mensajes que podían descartarse o recibirse fuera de servicio, y usaban una conexión TCP paralela para obtener información que debía ser confiable.

Dado que el usuario promedio tiene conexiones de red más rápidas ahora, ¿puede un juego en tiempo real como un FPS ofrecer un buen rendimiento a través de una conexión TCP?


Respuestas:


36

Yo diría que no. La información espacial de los objetos del juego debe ser lo más rápida posible, y para eso es mejor usar UDP, ya que la confiabilidad no es 100% crítica. Incluso en las conexiones modernas, UDP sigue siendo lo suficientemente lento como para tener que hacer algunas consideraciones especiales para la interpolación y demás. Incluso solo en términos de la cantidad de datos transferidos, TCP agregaría una sobrecarga significativa a esto.

Sin embargo, TCP es perfectamente aceptable para cosas que no son en tiempo real, como negociación multijugador, mensajes de chat, actualizaciones de puntajes, etc.


77
Sean está más o menos en el dinero. Si, por casualidad, estás desarrollando un juego en C # /. NET (¡sabes que quieres hacerlo!), He encontrado que la Biblioteca de red Lidgren ( code.google.com/p/lidgren-library-network ) es bastante buena elección. Incluso proporciona mensajes ordenados y confiables a través de UDP, en caso de que lo necesite.
Mike Strobel

2
No es prudente mezclar TCP y UDP; Como resultado de la forma en que TCP realiza el control de flujo, puede inducir la pérdida de paquetes. (fuente: isoc.org/INET97/proceedings/F3/F3_1.HTM )
Jason Kozak

44
También es importante tener en cuenta que, en algunos casos, sus usuarios finales estarán detrás de los ISP que bloquean el tráfico UDP, tienen configuraciones de enrutador que evitan el tráfico UDP, o de lo contrario se encuentran en una situación en la que el uso de UDP es menos que ideal. En esos casos, si tu juego puede soportarlo, ser capaz de recurrir a la comunicación TCP es bastante útil.
Charles Ellis

Otro punto positivo para UD es que está naturalmente orientado a paquetes, debe emular esto en TCP si es necesario (código de placa de construcción), lamentablemente los protocolos más modernos no son compatibles con Windows (esto apesta)
Quonux

11

Como Flash no es compatible con UDP, al mirar los juegos Flash multijugador puedes tener una idea bastante clara de lo que es posible con TCP / IP y lo que no. Básicamente, puedes crear juegos en tiempo real, siempre que no dependan de tiempos de respuesta ultrarrápidos. Un par de ejemplos:

http://www.xgenstudios.com/play/stickarena

http://everybodyedits.com/

Si tiene la opción de usar UDP, realmente debería hacerlo, pero con Flash lamentablemente no obtiene esa opción.


8

Depende.

Juegos como World of Warcraft usan TCP para su comunicación, porque eludir muchos problemas al usarlo. Como resultado, puede haber un ping más alto, pero para muchos juegos, esto es aceptable. Debe hacer una interpolación espacial incluso cuando utiliza UDP como protocolo.


1
No es solo ping. Hay una razón por la cual no hay colisiones jugador-jugador en WoW. Sería muy difícil hacerlo bien. WoW puede usar TCP porque no importa mucho dónde esté parado. Apuntar y atacar no depende de la posición real del monstruo o jugador enemigo. Si te interesan estas cosas, entonces TCP dañará la experiencia de juego.
Nuoji

6

Si la arquitectura de su cliente / servidor es limpia, la capa de transporte (casi) no importa.

TCP tiene algunos inconvenientes, pero estos son fáciles de evitar.

Entonces sí, TCP y un cerebro es todo lo que necesitas.

Con configuraciones de red comunes (proxies, cortafuegos, etc.) hoy en día UDP es prácticamente inútil para todos los juegos, excepto locales (léase: LAN).


77
Si vota negativamente, por favor deje un comentario. Usamos TCP y nunca tuvimos un solo problema con él.
Andreas

3
No veo la relevancia de las configuraciones de red comunes en esto. Los cortafuegos generalmente interfieren solo con servidores de alojamiento, pero incluso así, independientemente del protocolo, mientras que los servidores proxy aumentan el riesgo de paquetes retrasados ​​o descartados, lo que hace que UDP sea mucho más útil de lo que sería en una red local. Los inconvenientes de UDP se pueden eludir en gran medida haciendo comprobaciones de integridad usted mismo, pero no puede eliminar las funciones de TCP para hacerlo más rápido.
Marks Thomas

1
Tienes que mencionar a Nagles . Siempre olvido que esa es la causa principal por la cual TCP es malo (Nagle almacena paquetes en el cliente / servidor, básicamente "retirándolos" de su juego e introduciendo demoras adicionales).
bobobobo

Existen varias razones por las que debería usar UDP en lugar de TCP si la latencia es una preocupación. Si no le importa la latencia y / o puede hacer suficiente predicción del lado del cliente, entonces TCP puede ser suficiente. En el caso de los juegos en tiempo real. Olvídate de TCP.
Nuoji

6

Es perfectamente aceptable usar TCP en lugar de UDP, si desactiva el algoritmo de Nagle .

Una vez que apaga Nagle, tiene la mayor parte de la velocidad de UDP y podrá hacer un juego de reacción de contracción . De hecho, he creado un juego con TCP en Flash:

http://2dspacemmo.wildbunny.co.uk

¡Espero que ayude!


Aplicación no operativa en su enlace, señor.
Ingeniero

Enlace completamente podrido, señor. Recibo una prueba de servidor Apache.
Gustavo Maciel

4

Para los juegos FPS siempre usamos UDP. Especialmente si estás haciendo un tiroteo donde los pings son importantes.


4

Depende del tipo de juego.

Algunos juegos, como RTS, juegan mucho mejor a través de TCP y generalmente usan TCP todo el tiempo.

El verdadero problema con TCP es que si se pierde el paquete, incluso una pequeña cantidad, la conexión se "detiene" hasta que se produce la retransmisión. El sistema operativo no puede entregar datos fuera de servicio a la aplicación (esto rompe las garantías de TCP, pero también, TCP no muestra los límites de trama de la aplicación). El bloqueo de la conexión significa que posteriormente llegan datos tardíos. Pero en un (por ejemplo) juego FPS, los datos desactualizados son inútiles.

Con UDP, la aplicación puede elegir qué hace con los datos tardíos o fuera de servicio. Puede (y para un juego como FPS, generalmente lo hace) ignorar datos antiguos y simplemente tomar los últimos. Un paquete perdido ocasional no retrasa los paquetes posteriores en absoluto. Si finalmente llega un paquete retrasado, el juego puede ignorarlo.


Tenga en cuenta que su implementación necesitará manejar el aspecto de descartar paquetes retrasados, ya que UDP lo tratará como un datagrama recibido.
Guvante

3

No acepte simplemente una respuesta directa "sí o no porque lo dije" aquí, ya que puede estar abriéndose a tener que luchar contra un montón de problemas con UDP que en realidad no necesita enfrentar.

Ninguna de las otras respuestas aquí indica la forma obvia de probar esto.

Toma algunos hechos simples

  • Un encabezado IP tiene 20 bytes sin importar el protocolo que use.
  • Los encabezados UDP son de 4 bytes
  • Los encabezados TCP son de 20 bytes

Por lo tanto, cada vez que envía un mensaje de 1 byte en la línea, realmente ha enviado 25 o 41 bytes, según el protocolo, suponiendo que también se necesita un encabezado IP.

fuentes:

Mi consejo

Tome su situación en la que necesita la interacción del servidor del cliente, calcule el número de clientes y luego haga los cálculos en función de los datos que realmente envía entre los 2.

Un ejemplo

Digamos que envío 10 mensajes que son 1 byte cada uno por actualización en mi juego y estoy actualizando alrededor de 60 fps, así que necesito enviar 60 * 10 = 600 bytes por segundo de datos de mensajes reales + los encabezados relevantes.

Ahora, dependiendo del juego, podría enviarlo todo como un solo mensaje, por lo que mi sobrecarga de la capa TCP es de solo 40 bytes (efectivamente, un costo sobre UDP de 20 bytes por segundo), no tener esa sobrecarga es un costo potencial de 600 bytes ( porque puede que tenga que volver a enviar toda la secuencia de mensajes

Sin embargo, si es de vital importancia que cada mensaje se envíe por sí solo en el mismo instante en que está listo para ser enviado, tengo 600 mensajes (también 600 bytes) + 40 * 600 = 24k de sobrecarga TCP o ~ 14k de sobrecarga UDP por segundo + 600 bytes de datos del mensaje.

Una vez más, hacemos las preguntas, ¿qué tan vitales son esos mensajes, qué tan frecuentes son y si se pueden agrupar de alguna manera para reducir los gastos generales?

Eso se basa solo en un montón de mensajes de un solo byte, por lo general, haría algo muy diferente, pero sin saber que los datos sin procesar se envían es difícil de probar de cualquier manera si TCP se ajusta mejor a su situación que UDP.

Entonces, ¿funcionará?

Bueno, si tiene un fps típico y la posición es importante (para evitar trampas o decisiones incorrectas), debe saber que su transmisión de red es confiable, pero 32 reproductores transmiten cada uno más de 24k bytes de mensajes de ida y vuelta (por lo tanto, 768KB / s + mensajes) ... se trata de una línea de banda ancha de 10 mb / s solo para encabezados individuales basados ​​en el envío de al menos 1 mensaje por cuadro de cada cliente a todos los demás clientes a través de un servidor.

Obviamente, no codificará su servidor y cliente para que funcionen de esa manera y es muy probable que los tamaños de los mensajes sean mucho más grandes y probablemente un poco menos frecuentes que 1 byte por cuadro en la mayoría de las situaciones, por lo que es difícil de decir sin ver un mundo real Ejemplo de "esta es la información que necesito enviar".

Mi caso

En mi caso, hice la llamada de que es una sobrecarga razonable, pero eso se basa en cómo construyo mis flujos de mensajes para que no tenga grandes gastos generales en comparación con algunos diseños.

TCP funciona bien y tengo un servidor MMO escalable y un marco de cliente, pero no necesito transmitir una gran cantidad de datos o muchos paquetes pequeños porque puedo agrupar mis llamadas.

para otros: TCP simplemente no funciona, y solo pueden usar UDP, pero tienen que aceptar que no les dará garantías sobre lo que obtienen (pedido / garantía de llegada).

Otras Consideraciones

Muchos motores de juegos mal codificados manejan todo en el hilo principal de la CPU, por lo que a la CPU a menudo solo se le da una cantidad muy pequeña de tiempo para manejar el código de red, una implementación decente tanto del servicio como del cliente sería completamente asíncrona y posiblemente presionar y extraer mensajes en lotes.

Hay algunas buenas bibliotecas de redes, pero como se ve aquí, muchas parecen tener la opinión de que UDP es "simplemente mejor", tenga en cuenta primero sus propias necesidades y ese puede no ser el caso, y encontrar una biblioteca que no Tenga en cuenta las cosas de la manera en que lo hace puede dar como resultado una configuración de TCP mal codificada en comparación con la variante UDP en la misma biblioteca (solo digo que he visto esto y las pruebas de carga lo han demostrado).

Cree algo primero, una base técnica de los datos que desea enviar y pruébelo, luego haga los cálculos para escalarlo, en el peor de los casos, pruébelo al implementarlo en una nube y haga que 50 computadoras ejecuten un cliente de prueba para ver si puede manejar su límite de 32 jugadores por juego (o los límites que pueda tener).


2

No lo creo ... Los juegos donde la transferencia de datos es muy frecuente (al mover el mouse o al presionar una tecla), deberían usar UDP. Se retrasará incluso en LAN si se usa TCP.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.