¿UDP es aún mejor que TCP para juegos en tiempo real con muchos datos?

71

Sé que UDP generalmente se recomienda para juegos multijugador en tiempo real con alto uso de datos.

La mayoría de los artículos tienen años de servicio, y dado que ~ 80% de todos los datos transmitidos en Internet son TCP, se debe haber hecho mucha optimización para TCP.

Esto me hace preguntarme: ¿UDP sigue siendo superior en términos de velocidad y latencia? ¿Podrían las optimizaciones TCP recientes haber hecho que TCP funcione mejor que UDP?

KaareZ
fuente
25
Con UDP no hay garantía de que sus paquetes sean recibidos o incluso pedidos, eso solo hace que UDP sea más rápido que TCP.
nathan
44
@KaareZ, ¿qué quieres decir con una implementación más rápida?
nathan
2
@nathan Que es más fácil desarrollar su aplicación con TCP que UDP. Quiero saber si todas las optimizaciones de TCP han hecho de TCP una mejor opción en términos de rendimiento.
KaareZ
3
@KaareZ no soy un experto, pero pensemos en ello. ¿Cómo podría TCP ser mejor en términos de rendimiento y seguir siendo un protocolo confiable? No puedes tenerlo todo. TCP está hecho para la confiabilidad. La verdadera pregunta es ¿por qué querrías usar TCP en tu juego?
nathan
77
UDP es mejor que TCP si y solo si puede (= programador experimentado de redes de bajo nivel) volver a implementar solo las características TCP que necesita dentro de él de manera efectiva. Eliminando las características TCP innecesarias para el rendimiento.
wondra

Respuestas:

119

No, UDP sigue siendo superior en términos de latencia de rendimiento y siempre será más rápido, debido a la filosofía de los 2 protocolos: suponiendo que sus datos de comunicación se diseñaron teniendo en cuenta UDP o cualquier otra comunicación con pérdida.

TCP crea una abstracción en la que llegan todos los paquetes de red, y llegan en el orden exacto en que fueron enviados. Para implementar tal abstracción en un canal con pérdida, debe implementar retransmisiones y tiempos de espera, que consumen tiempo. Si envía 2 actualizaciones en TCP y se pierde un paquete de la primera actualización, no verá la segunda actualización hasta que:

  1. Se detecta la pérdida de la primera actualización.
  2. Se solicita una retransmisión de la primera actualización.
  3. La retransmisión ha llegado y ha sido procesada.

No importa qué tan rápido se haga esto en TCP, porque con UDP simplemente descartas la primera actualización y usas la segunda, más nueva, en este momento. A diferencia de TCP, UDP no garantiza que lleguen todos los paquetes y tampoco garantiza que lleguen en orden.

Esto requiere que envíe el tipo correcto de datos y diseñe su comunicación de tal manera que sea aceptable perder datos.

Si tiene datos a donde debe llegar cada paquete, y su paquete debe procesarlos en el orden en que fueron enviados, entonces UDP no será más rápido. De hecho, usar UDP en este caso probablemente sea más lento porque está reconstruyendo TCP e implementándolo por medio de UDP, en cuyo caso también podría usar TCP.

EDITAR: agregar información adicional para incorporar / abordar algunos de los comentarios:

Normalmente, la tasa de pérdida de paquetes en Ethernet es muy baja, pero se vuelve mucho más alta una vez que WiFi está involucrado o si el usuario tiene una carga / descarga en progreso. Supongamos que tenemos una pérdida de paquetes perfectamente uniforme de 0.01% (unidireccional, no ida y vuelta). En un juego de disparos en primera persona, los clientes deben enviar actualizaciones cada vez que sucede algo, como cuando el cursor del mouse gira el reproductor, lo que ocurre aproximadamente 20 veces por segundo. También podrían enviar actualizaciones por cuadro o en un intervalo fijo, que serían 60-120 actualizaciones por segundo. Como estas actualizaciones se envían en diferentes momentos, se enviarán / deberían enviarse en un paquete por actualización. En un juego de 16 jugadores, los 16 jugadores envían estos 20-120 paquetes por segundo al servidor, lo que da como resultado un total de 320-1920 paquetes por segundo. Con nuestra tasa de pérdida de paquetes de 0.01%, esperamos perder un paquete cada 5.2-31.25 segundos.

En cada paquete que recibamos después del paquete perdido, enviaremos un DupAck, y después del tercer DupAck, el remitente retransmitirá el paquete perdido . Por lo tanto, el tiempo que TCP requiere para iniciar la retransmisión es de 3 paquetes, más el tiempo que tarda el último DupAck en llegar al remitente. Luego, debemos esperar a que llegue la retransmisión, por lo que en total esperamos 3 paquetes + 1 latencia de ida y vuelta. La latencia de ida y vuelta suele ser de 0-1 ms en una red local y de 50-200 ms en Internet. 3 paquetes llegarán típicamente en 25 ms si enviamos 120 paquetes por segundo, y en 150 ms si enviamos 20 paquetes por segundo.

En contraste, con UDP nos recuperamos de un paquete perdido tan pronto como recibimos el siguiente paquete, por lo que perdemos 8,3 ms si enviamos 120 paquetes por segundo y 50 ms si enviamos 20 paquetes por segundo.

Con TCP, las cosas se vuelven más complicadas si también tenemos que considerar Nagle (si el desarrollador olvida desactivar la fusión de envíos o no puede deshabilitar el ACK retrasado ), evitar la congestión de la red o si la pérdida de paquetes es lo suficientemente mala como para tener que dar cuenta de múltiples pérdidas de paquetes (incluidas las pérdidas Ack y DupAck). Con UDP podemos escribir fácilmente un código más rápido porque simplemente no nos importa ser un buen ciudadano de la red como lo hace TCP.

Peter
fuente
Nota: UDP puede transmitir la red local (posible ventaja), y dado que Vista requiere que el administrador ejecute el servidor / transmisión en UDP (desventaja) (UAC / firewall tienden a fallar para informar que se requiere la acción del usuario).
PTwr
77
"Si envía 2 actualizaciones en TCP y se pierde un paquete de la primera actualización" Verdadero, pero ¿cuáles son las posibilidades de que eso ocurra? Según pingman : "Cualquier pérdida de paquetes superior al 2% durante un período de tiempo es un fuerte indicador de problemas".
mucaho
30
@ Peter se está olvidando de que en TCP cada paquete descartado se detiene en cada paquete posterior. Con un ping de 100 ms, podría ser fácilmente 300-500 ms antes de que ese paquete se retransmita y reciba, por lo que son 6-10 paquetes que se estancan cada 33 segundos. Eso definitivamente se notará en un FPS similar a un terremoto.
BlueRaja - Danny Pflughoeft
12
En muchas implementaciones de TCP, el primer tiempo de espera después de un ack perdido tomará un segundo completo. Eso es mucho tiempo Si los paquetes son pequeños, UDP podría suavizarse fácilmente sobre una transmisión perdida o dos simplemente haciendo que cada paquete incluya datos de las últimas dos actualizaciones para que la aplicación obtenga los datos que necesita antes de que el remitente o el receptor puedan saber que el primer paquete se perdió.
supercat
23
Con un juego como Quake, perder el primer paquete es irrelevante. En MUCHO menos tiempo, le llevaría detectar la pérdida y retransmitir el primer paquete, ya debería haber transmitido un segundo paquete que hace que el primero quede obsoleto de todos modos. Esta es la misma razón por la que muchas aplicaciones de voz y video en tiempo real también usan UDP. Si se cae un paquete, preferiría simplemente perder 0.02 segundos de audio que retrasar la transmisión completa en un segundo o más. Lo mismo es generalmente cierto con los juegos en tiempo real, ya que desea saber dónde está un objeto ahora , no hace 1,5 segundos.
reirab
19

Estamos de acuerdo en que tanto TCP como UDP son protocolos construidos sobre IP , ¿no? IP especifica cómo se entregan los mensajes a través de Internet, pero nada se trata de la estructura y el formato de los mensajes. Aquí vienen los protocolos TCP y UDP. Utilizan las propiedades de IP, pero permiten que el programador se concentre en el intercambio de mensajes sin preocuparse por las capas más bajas de la comunicación de red. Y eso es genial, porque tratar con señales analógicas en cables directamente sería un poco doloroso.

  • TCP proporciona un conjunto de funciones para enviar y recibir mensajes. Divide nuestros datos en pequeños paquetes para nosotros y los enviamos a través de la red. Todo lo que se nos pide es un puerto para usar para el socket de red y el mensaje real que queremos enviar. Además, es confiable, lo que significa que si algunos paquetes se pierden a lo largo de la red que se detectan, luego se envían nuevamente con el cuidado de enviarlos en el mismo orden en que se suponía que llegarían.

  • Por otro lado, UDP es un protocolo orientado hacia el control del usuario. Cuando usamos UDP para enviar nuestros datagramas , no podemos estar seguros de si el datagrama llegará alguna vez a destino o no (y queremos decir certeza matemática aquí: cuando enviamos un paquete probablemente llegará, pero no podemos estar seguros de 100%) Además, cuando se pierde un paquete, no se detectará ni se volverá a enviar.

En este punto, TCP sería la solución ideal para todos nuestros problemas. Es confiable, es rápido, resuelve la latencia de conexión para nosotros al realizar un seguimiento de qué paquetes llegaron y qué paquetes aún tenemos que enviar.

PERO , mira más allá. La única ventaja que nos brinda UDP es su velocidad, y eso es lo que realmente queremos. Un paquete UDP se crea, se envía y se envía sin ningún control en particular, porque así es como funciona el protocolo UDP. Un paquete TCP debe ser diseñado, etiquetado, marcado, y cuando llegue, se enviará un ACK para decirle al remitente "el paquete x está aquí, continúe" , y cuando esta señal no se envía, eso significa que dicho paquete x debe enviarse de nuevo.

Sé que UDP generalmente se recomienda para juegos multijugador en tiempo real con alto uso de datos.

Sí, pero no solo UDP es ampliamente preferido sobre TCP principalmente porque su alta velocidad es idea para manejar el envío y la gestión de datos de alta. Esto sucede cuando, suponiendo que dicho videojuego se ejecute en un bloqueo determinista (lo que sucede en el servidor se replica idénticamente en cualquier cliente independientemente de la latencia de la red), se pierde un paquete de actualización y nunca llega a su destino. TCP volvería a enviar dicho paquete, y los siguientes paquetes se descartan porque no llegan en orden, y luego se vuelven a enviar después del perdido. UDP es mucho más tolerante en este escenario: no le importará este paquete, porque las actualizaciones más recientes están por llegar. La actualización perdida no se procesa, sino que la física del juego se interpola según el método de integración utilizado y la última actualización recibida.

TCP provoca fluctuaciones cuando la latencia es lo suficientemente alta, UDP no:

<video style="min-width: 100% height: auto" autoplay="" preload="auto" loop="true"><source src="https://gafferongames.com/videos/deterministic_lockstep_tcp_250ms_5pc.mp4" type="video/mp4"><source src="http://173.255.195.190/cubes_deterministic_lockstep_tcp_250ms_5pc.webm" type="video/webm">Your browser does not support the video tag.</video>

Esto me hace preguntarme si UDP sigue siendo superior en términos de velocidad y latencia.

Bueno, sí, lo es y lo hará por mucho tiempo. Puede leer más sobre TCP vs UDP aquí .

liggiorgio
fuente
8
TCP utiliza flujos de bytes en lugar de datagramas. UDP usa datagramas. Las buenas implementaciones de TCP mantendrán los paquetes que llegan fuera de servicio, pero el contenido de los paquetes no estará disponible para la aplicación a menos o hasta que se hayan recibido todos los paquetes anteriores. Por lo tanto, si se pierde un paquete, el remitente podría no necesitar retransmitir todo lo que siguió al paquete perdido, pero la aplicación receptora no vería nada más allá del paquete perdido hasta que ese paquete se retransmita (con lo cual la aplicación vería instantáneamente el contenido de ese paquete). paquete y los que están después).
supercat
@supercat Desafortunadamente, TCP no tiene forma de decirle al remitente exactamente qué paquetes recibió y no recibió. Solo tiene un mecanismo para "He recibido todos los bytes hasta el número de secuencia x". Si el remitente retransmite los paquetes que el receptor ya recibió, simplemente ignorará las copias.
reirab
@reirab: pensé que había algunas extensiones modernas que incluían esa característica, aunque incluso sin eso, creo que una implementación que había enviado datos hasta el byte # 1,050,000 pero solo recibió reconocimientos por datos de hasta 1,000,000, después de un segundo sin escuchar cualquier reconocimiento de más de 1,000,000, comience enviando un bloque de datos de 1,000,000 a 1,000,500 más o menos y luego esperando una respuesta. Si obtiene un reconocimiento de datos de hasta 1,000,500, puede retransmitir más datos; Si obtiene un reconocimiento de datos de hasta 1,050,000, puede omitir las retransmisiones.
supercat
1
@Giorgio IP no especifica nada acerca de las señales analógicas. Eso se hace en la capa física. IP opera dos capas por encima de la capa de red. A IP no le importa si los bits pasan por fibra, un enlace satelital o un módem de acceso telefónico de 14.4 kbps. UDP y TCP son una capa desde IP, en la capa de transporte. Además, como dice supercat, TCP presenta una interfaz de flujo a la aplicación, no una interfaz de datagrama como UDP.
reirab
@supercat Hmm ... puede que tengas razón sobre las extensiones modernas, aunque ciertamente no es parte del estándar TCP original. Un ACK solo tiene un número de secuencia. Supongo que una implementación de TCP normalmente comenzaría a retransmitir toda la ventana de envío si se cae un paquete en lugar de esperar un RTT completo para cada paquete. Eso agregaría una gran cantidad de latencia si se perdieran varios paquetes consecutivos con muy poca ganancia.
reirab
9

TCP <- Protocolo de control de transmisión . Está hecho para controlar la transmisión.

TCP fue creado para ser un buen ciudadano de la red diplomática. Se centra en hacer que la creación de redes sea una buena experiencia para todos, y voluntariamente disminuye su rendimiento para lograrlo. Se ajusta al entorno agregando latencia . Las razones son, por ejemplo:

  • El receptor detecta un paquete perdido, le dice al remitente que disminuya la velocidad (reduzca a la mitad la velocidad por un tiempo).
  • El receptor detecta un orden incorrecto de paquetes entrantes (tal vez tomaron diferentes rutas de red), le dice al remitente que disminuya la velocidad, y por cierto, el receptor no aceptará más paquetes hasta que llegue el que falta. Tratar con esto lleva tiempo.
  • El remitente detecta la congestión de la red (por ejemplo, tiempo de ida y vuelta lento), agrega latencia.
  • El receptor no puede mantenerse al día con la velocidad (el búfer de entrada se está llenando demasiado), le pide al remitente que agregue latencia (control de flujo).
  • Hay un único receptor lento (bastardo de ping alto, llorón, cómo se llaman) entre los receptores, se puede agregar latencia en el hogar.

Adicionalmente

  • El algoritmo de Nagle puede mantener los datos de los remitentes en espera, hasta que haya más para enviar (para utilizar marcos de datos de manera más eficiente). Los datos críticos de tiempo se retrasan.
  • Creo que los enrutadores domésticos comunes con wlan pueden hacer cosas inteligentes (reducir la velocidad) para suavizar el rendimiento de TCP entre varios clientes (la interfaz wlan es el cuello de botella, incluso si el juego no lo usa). Se relaciona con la transmisión / multidifusión, es decir. "otros" datos pueden disminuir su rendimiento TCP.
  • TCP AC reconoce todo, lo que no es necesario para un entorno de juego. No tiene sentido ACKing cada actualización física. Suficiente para reconocer, por ejemplo, una vez por segundo, o similar. Si un cliente (o un servidor) permanece en silencio durante más tiempo, entonces es hora de reaccionar.

A pesar de esto, TCP proporciona la cifra más alta para (datos transmitidos en general) / (tiempo total consumido). Solo que no sucede precisamente cuando quieres que suceda.

UDP no hace nada de esto. Se dispara a su voluntad, solo que uno no puede esperar que golpee cada vez; en lugar de eso, el objetivo debe anunciar que "no ha disparado en mucho tiempo, ¿por qué?". Todavía se pueden crear paquetes ACK personalizados, colocar múltiples registros en un solo paquete, etc. Y también es importante, controlar el recorrido NAT. UDP es sin duda adecuado para juegos con baja demanda de latencia.

Ventormenta
fuente
1
Nota: el algoritmo de Nagle se puede desactivar, por ejemplo , para Linux .
mucaho
Nagle puede funcionar en contra (y puede evitarse configurando cada paquete para que la aplicación lo "empuje"), mientras que Delacked Ack funciona a favor de TCP, le permite al remitente colocar más bytes en el cable hasta que la ventana de envío esté llena (idealmente tan grande) ya que el búfer de recepción está en el otro lado) independientemente de si se ha visto un reconocimiento.
Jeff Meden
44
Es el protocolo de control de transmisión .
ysdx
1
Escriba estas palabras un millón de veces ... gracias - arreglado.
Ventormenta
3

Puede comparar el primer diagrama de RFC 768 (UDP) con el primer diagrama de RFCP 793 (TCP) página 15 .

Ambos muestran 16 bits para un "puerto de origen" seguido de 16 bits para un "puerto de destino". Ambos muestran 16 bits para una "suma de verificación". Según RFC 768, el "procedimiento de suma de verificación de UDP es el mismo que se utiliza en TCP".

Mientras que la longitud de UDP envuelve los detalles del diagrama de UDP, la longitud de TCP es parte de un "pseudo encabezado de 96 bits" descrito en las páginas 15 y 16.

No espere que TCP supere a UDP. Eso simplemente no es probable que ocurra, por múltiples razones. Una es que TCP simplemente tiene más bits. Entonces, si el equipo puede procesar efectivamente un cierto número de bits por segundo, eso permitirá más paquetes UDP que paquetes TCP.

La otra razón es que el "protocolo de enlace de tres vías" de TCP significa que el remitente debe esperar una respuesta. Este requisito introduce una sobrecarga adicional que UDP no maneja. Hay una razón por la cual la mayoría de sus comunicaciones por Internet comienzan con alguna comunicación UDP. El DNS básico utiliza UDP porque una solicitud y una respuesta se pueden completar en menos pasos que el proceso de "protocolo de enlace de tres vías" de TCP. La característica de TCP de realizar un seguimiento de los paquetes perdidos es bastante poco emocionante, porque una computadora podría simplemente hacer una nueva solicitud en lugar de tratar de informar a un sistema remoto que hay una solicitud previa no cumplida.

TOOGAM
fuente
Aunque los resúmenes en inglés (como se ve en algunas otras respuestas) son agradables, tener algunas descripciones precisas y precisas puede ser más simple.
TOOGAM
¡Quieres decir 16 bits, no bytes!
jcaron
Oh, tonto de mí. Es un ejemplo de por qué las respuestas técnicamente precisas son buenas; son fáciles de identificar errores y ver la información correcta. Arreglé la respuesta. Gracias @jcaron
TOOGAM
2

Considera lo que sucede por un momento. Para simplificar los escenarios, tienes dos opciones cuando intentas enviar un cambio de estado (como que tu jugador acaba de cambiar de dirección, o disparó un arma, o algún otro jugador simplemente lanzó una bomba):

  1. Mantenga abierta una sesión TCP, y cuando la bomba vaya a estallar, envíe un mensaje TCP a todos los jugadores (si es posible, vea a continuación)
  2. Mantenga un puerto UDP escuchando y cuando la bomba explote, envíe un mensaje UDP a todos los jugadores sin importar su estado de conexión

Suponiendo que no se necesitaba una actualización justo antes, el momento en que llegue esa actualización singular en 1 vs 2 no será muy diferente. Es un viaje del servidor al cliente. Pero, digamos que en lugar de que solo explote una bomba, está tratando de transmitir continuamente la actividad de alguien corriendo por un laberinto; tejido, agacharse, disparar, etc. En el caso de UDP, cada acción se enviará en un datagrama, tan pronto como suceda. En el caso de TCP, cada acción se enviará en un paquete solo si el servidor puede enviar. ¿Qué dice que está permitido enviar? Tener espacio en la ventana TCP (suponiendo que el reconocimiento retrasado esté activo) para que el mensaje se pueda colocar en el cable. Si no, tiene que esperar a que llegue un reconocimiento del cliente antes de enviarlo.

¿Cuánto tiempo es demasiado largo? Cuando el desarrollo del juego de disparos en primera persona multijugador llegó a su final a finales de los 90 y principios de los 2000, las conexiones de baja latencia no eran comunes. Un módem de acceso telefónico tendría una latencia unidireccional típica de 180 ms. Esperar un momento antes de enviar otra actualización, duplicando efectivamente ese tiempo a 360 ms, fue doloroso; incluso los usuarios novatos definitivamente podrían sentir la diferencia. Cuando las conexiones de banda ancha se pusieron de moda, redujeron mucho la latencia, pero persistió cuando el ancho de banda era escaso (con frecuencia en algunas áreas). Por lo tanto, la preferencia por la latencia más baja posible persistió.

Las conexiones e interconexiones hogareñas modernas han cambiado esto, hasta el punto en que la latencia regional, incluso durante los momentos congestionados del día, está en el rango de 15 ms o menos. Elegir TCP en lugar de UDP sería invisible en la mayoría de los casos, ya que la latencia es "lo suficientemente baja". Sin embargo, todavía existe la tendencia de que UDP tenga prioridad sobre TCP dado su historial como un protocolo de baja latencia. Entonces, por ahora (y probablemente en algún momento en el futuro) UDP será preferido para la comunicación en tiempo real.

Jeff Meden
fuente
La latencia sería lo suficientemente baja, excepto que, de manera predeterminada, las escrituras TCP solo se envían cuando los datos para escribir cruzan un cierto umbral o un tiempo de espera (generalmente 200-1000 ms). Si necesita TCP en un sistema de baja latencia con poco rendimiento, debe deshabilitar esta función y asegurarse de no escribir bytes individuales todo el tiempo (por ejemplo, ya no trata la transmisión TCP como transmisión, y finge que se trata de mensajes individuales en su lugar). No tienes que esperar el ACK a menos que tus buffers estén llenos, lo cual es bastante improbable que ocurra en un juego típico en tiempo real.
Luaan
1
@Luaan Enter: el indicador TCP PSH. Cuando una aplicación lo entrega a la pila, el paquete se envía inmediatamente sin esperar más datos. Muchas aplicaciones usan esto con éxito (telnet y ssh, por ejemplo).
Jeff Meden
2

Sé que UDP generalmente se recomienda para juegos multijugador en tiempo real con alto uso de datos.
¿UDP sigue siendo superior en términos de velocidad y latencia? ¿Podrían las optimizaciones TCP recientes haber hecho que TCP funcione mejor que UDP?

Tus suposiciones están equivocadas. TCP y UDP difieren principalmente en qué modelo representan (datagramas poco confiables versus flujo virtual confiable en orden).

No difieren con respecto al volumen ("alto uso de datos") o el rendimiento. TCP empujará tantos datos como UDP, saturará fácilmente el cable físico.

En presencia de pérdida de paquetes, los dos difieren en latencia, pero solo en esa condición. De lo contrario, TCP tiene una latencia tan baja como UDP (más o menos unas pocas docenas de nanosegundos porque la pila de red tiene un poco más de lógica que hacer, pero eso es bastante despreciable).
Hay una ligera diferencia en el tamaño del encabezado, por lo que técnicamente, más bytes deben pasar por el cable en las líneas seriales, pero ese también es bastante intrascendente. Realmente solo importa para transferencias masivas, y luego se trata de una diferencia de 0.5%. La mayoría de las personas con acceso a Internet DSL en el hogar enrutan todo su tráfico a través de ATM, lo que agrega más del 10% de sobrecarga de protocolo (5 bytes de control para 48 bytes de carga útil, más tramas parciales), y nadie se da cuenta.

Algunas personas construyen confiabilidad sobre UDP. Si se desea cierto nivel de confiabilidad, pero no se necesita una entrega estricta en orden, eso puede dar una pequeña ventaja. Sin embargo, todavía es discutible si el enfoque tiene mucho sentido y si paga un precio considerable por esa pequeña ventaja.
Si tiene clientes que se conectan desde WiFis del hotel u otros lugares "extraños", notará que a menudo el soporte general para TCP es mucho, mucho mejor que para UDP.

Los juegos generalmente usan UDP no porque sea superior en una de las formas mencionadas, no lo es, o porque puede reducir la fluctuación de fase en medio milisegundo implementando confiabilidad sin orden, sino porque los juegos (al igual que la telefonía IP) a menudo contienen muchos datos muy volátiles, como por ejemplo actualizaciones de posición.
Estos datos volátiles son obsoletos de manera regular y rápida tanto por el paso del tiempo como por el próximo datagrama que ingresa. Lo que significa nada más y nada menos que realmente no te importa demasiado ser 100% confiable (o en orden).

Suponiendo que un paquete de red se descarta en un servicio que se ejecuta a un ritmo constante con actualizaciones frecuentes (juego de disparos, teléfono, video chat), no tiene mucho sentido tener el tiempo de confirmación y reenviar el paquete, y mientras tanto congele todo en el otro extremo mientras espera que llegue el paquete reenviado. Eso es demasiado inquietante, y no es bueno.

En cambio, solo considera el paquete perdido y sigue adelante, tomando los datos del siguiente paquete que lo atraviesa y, mientras tanto, lo mejor que pueda, oculta el hecho de que el usuario perdió un paquete. Interpolación, cálculo muerto, lo que sea.

Tenga en cuenta que la pérdida de paquetes es una condición normal. Si bien la IP es generalmente "bastante confiable", los paquetes que se descartan ocasionalmente pueden suceder y sucederán . Si bien los paquetes que se pierden normalmente son más bien raros (<1% aquí), no es algo extraordinario o teórico, o una indicación de que algo está roto. Es perfectamente normal.
Cada transferencia masiva TCP necesariamente incluirá paquetes perdidos, por ejemplo (así es como funciona el control de congestión).

Damon
fuente
2

En un MPG de ancho de banda alto, no te importa si te perdiste un paquete que te da la ubicación y el estado del monstruo # 425, porque recibirás otra actualización en una fracción de segundo. Este es un ejemplo en el que UDP hace que TCP parezca estúpido por hacer que espere datos instantáneamente obsoletos.

En ese mismo juego, quieres que los parches se muestren exactamente como fueron diseñados. TCP ya tiene incorporadas las funciones "dime si falla", lo que facilita los reintentos automáticos y las fallas verificadas. Puedes hacerlo en UDP, pero ¿por qué recrear la tecnología?

Aquí hay una descripción simple de lo que está sucediendo.

UDP: aislar el fragmento O'data.
Haz un paquete
Encapsular en IP.
Envíalo.

TCP: aísla un flujo de datos.
Haga un paquete desde el frente de la secuencia.
Encapsular en IP.
Espere espacio en la ventana TCP.
Envíalo.
Siga reenviando hasta que se reciba un recibo o se agote el tiempo de espera.
Permanezca en la ventana TCP hasta que se reciba un recibo o se agote el tiempo de espera.

El envío solo significa que lo hizo a través de la NIC local, no más.

Una recepción de recibo TCP garantiza la recepción de datos y libera espacio en la ventana para el siguiente paquete.

Reenviar (ligeramente) aumenta la probabilidad de un eventual recibo.

Los paquetes TCP se vuelven a ensamblar en el otro lado como una secuencia ordenada de datos. Los paquetes UPD se reciben como paquetes distintos. El protocolo no conserva el orden.

TCP es bueno para enviar datos requeridos y grandes cantidades ordenadas de datos. TCP proporciona notificación de una falla persistente. TCP se auto-acelera a través de tuberías estranguladas (ref: ventana). TCP tiene apretones de manos para ralentizar la inicialización. TCP requiere una "conexión" antes de la transmisión.

UDP solo pone los datos en el cable y le permite continuar sin esperar ventanas y retransmisiones. UDP enviará datos a toda velocidad a una tubería obstruida, sin importar cuántos datos se pierdan.

Diseñé y escribí una utilidad de transporte de archivos UDP multicast aplicada comercialmente. He trabajado en pilas de IP. Estos son solo conceptos básicos, sin minucias. Explicar "enchufes, MTU y otros juguetes divertidos" fue un poco más allá de lo que sería útil para esta pregunta.

Ps (no puedo agregar comentarios para responder a los comentarios) UDP también es bueno para los datos que son deseables pero no necesarios. La corrección de errores de reenvío es un ejemplo de esto, muchos paquetes innecesarios pero deseables.

dusc2don
fuente
3
Su punto sobre los datos "obsoletos" es bueno. TCP es bueno para datos "más vale tarde que nunca", pero UDP es bueno para datos que serán útiles si llegan al destino rápidamente, pero inútiles si no lo hacen.
supercat
1

¿Todos los enrutadores optimizados TCP han hecho que TCP funcione mejor que UDP?

Una pregunta más es: ¿significa "datos pesados" que cargará escenas con frecuencia?

En caso afirmativo, es posible que deba enviar grandes cantidades de datos (> 1k) de manera intensiva, en los que TCP puede ser mucho más eficiente porque, especialmente en el lado del servidor, las NIC proporcionarán varias descargas en el mismo lote de ciclos. Una aplicación de espacio de usuario puede emitir grandes escrituras con TCP mientras que en UDP un intento de enviar más de bytes de tamaño de encabezados MTU causará fragmentación de IP y otros gastos generales que matarán el rendimiento

Vadim Suraev
fuente
Es un juego "voxel", así que sí, tendrá que enviar muchos datos de la escena.
KaareZ
@KaareZ Bueno, probablemente quieras enviarlos como mensajes independientes individuales en ese caso de todos modos, con tus propios mecanismos de retransmisión. Minecraft comenzó en TCP, y no se podía reproducir en Internet; El cambio a UDP fue una ocasión feliz para la mayoría de las personas. La idea principal es que cuando envía 20 fragmentos de datos de vóxel, y el primero se "pierde", no debería bloquear la visualización de los otros 19 fragmentos tan pronto como obtenga los datos; cuando descubres que falta el primero, retransmites. En TCP, todos esos 19 están paralizados como mínimo y retransmitidos en el peor de los casos.
Luaan
2
@Luaan Minecraft no ha cambiado a UDP para el juego real. Incluso las últimas versiones todavía usan TCP. No es una ocasión feliz ... :( La única parte de Minecraft que usa UDP es la lista de servidores, para hacer ping a servidores individuales y determinar si están en línea.
camerondm9
1

Ni UDP ni TCP (ni ninguna otra variante) es superior a la derecha , ni siquiera en términos de velocidad / latencia. Su elección debe hacerse según los requisitos de su aplicación. Para hacer esto, debe comparar las características que ofrece cada protocolo, dándose cuenta de que más características implican más sobrecarga. Por lo tanto, si el objetivo es minimizar la latencia o maximizar la velocidad, debe elegir un protocolo con la menor cantidad de funciones posible, pero manteniendo las funciones esenciales necesarias para cumplir con sus requisitos.

Una comparación de protocolos

En términos generales, UDP (User Datagram Protocol) ofrece la menor cantidad de características. Es simplista porque envía datos sin ningún tipo de recibo / acuse de recibo.

Por otro lado, TCP (Protocolo de Control de Transmisión) ofrece la mayor cantidad de características necesarias para una comunicación confiable y conectada. Una comunicación TCP envía duplicados o más paquetes y los etiqueta con información de pedido. Al recibirlo en el destino, se debe enviar un ACK (acuse de recibo) junto con la información sobre los paquetes que se perdieron para que el remitente original pueda reenviar esos paquetes perdidos. Si recuerdo correctamente, incluso los paquetes ACK pueden necesitar reconocimiento para la confiabilidad adecuada.


Ejemplo: llamada de conferencia de Skype

Para una llamada de conferencia de Skype, no es importante asegurarse de que todos los datos de video y audio se envíen / reciban de manera confiable. Hoy en día, UDP hace un gran trabajo al minimizar la pérdida de paquetes de todos modos. Lo importante es saber que no hay absolutamente ninguna garantía en UDP si la transmisión fue exitosa o no. Para los datos de audio / video en una llamada de conferencia, UDP es una opción adecuada porque nos preocupamos más por obtener datos en tiempo real (es decir, el más reciente). Si se pierden algunos paquetes aquí y allá, no interrumpirá la comunicación de manera dramática.

Sin embargo, en una llamada de conferencia, las personas pueden enviar mensajes instantáneos (IM) o enviar archivos. En estos casos, la confiabilidad es un requisito necesario para garantizar que los archivos y mensajes no se corrompan o pierdan. Para los mensajes instantáneos, es posible que no necesite el estado conectado que proporciona TCP. Un protocolo intermedio, como RUDP (UDP confiable) puede ser suficiente. Sin embargo, para los archivos, puede ser necesario tener el estado conectado que proporciona TCP.


Opciones de implementación

Si tiene una aplicación compleja o necesita optimizar su comunicación, entonces es beneficioso comenzar con una comunicación UDP. Luego, puede agregar todas las funciones que necesita en la parte superior. Esto le dará el mayor control sobre su comunicación de red.

Si tiene una aplicación simple donde no se requiere optimización, considere optar por uno estándar (UDP o TCP) para satisfacer sus necesidades. Eso le permitiría pasar a asuntos más importantes.

Nicholas Miller
fuente
1

Noté muchos comentarios en los que la gente cree que los paquetes TCP son más grandes que los paquetes UDP. No solo confíes en mí, lee la documentación. El protocolo es el siguiente: unos pocos bytes para el encabezado Ethernet (tipo de mensaje de 2 bytes, MAC de 48 bits, 6 bytes) (para Wifi, el encabezado puede diferir) 20 bytes para IP 20 bytes para TCP o UDP x bytes para el rango de datos x de 0 a aproximadamente 1500 (ver MTU) Por último, la suma de comprobación para asegurarse de que no se produjo corrupción en ese paquete Ethernet.

TCP permite enviar paquetes de "transmisión" más grandes de aproximadamente 64K. Este bloque "grande" en realidad está cortado en muchos paquetes Ethernet más pequeños.

Joust6809
fuente
¿Estás tratando de sugerir que los encabezados UDP y TCP son del mismo tamaño?
Cameron