¿Es posible garantizar la entrega de mensajes usando UDP en Node.js?

¿Cómo es posible garantizar la entrega de mensajes usando UDP en Node.js? Por ejemplo, podría reenviar el paquete si falla, pero ¿hay alguna forma de identificar cuándo falló? Además, ¿qué tan común es la pérdida de un paquete?

Si lo que realmente te estás preguntando es “¿cómo detecto paquetes perdidos”? Luego, la técnica general es hacer que el receptor envíe un acuse de recibo por cada paquete enviado. Si el transmisor no recibe un acuse de recibo, debe reenviar el paquete. Si el receptor obtiene paquetes duplicados, debe descartar el duplicado.

El esquema básico es este:

TX RX \ data `-----------------------------> ack / <-----------------------------' \ data `-------------------- - - - loss of data packet . . . timeout . \ data retransmit `-----------------------------> ack / <-----------------------------' \ data `-----------------------------> ack / - - - - -----------------' loss of ack packet . . timeout . \ data retransmit `-----------------------------> ack / <-----------------------------' 

Esta es esencialmente la base de todas las formas de detección de pérdida de paquetes. Hay varias mejoras que pueden implementarse para mejorar la técnica, pero lo básico es generalmente el mismo: si el receptor no le dice que el paquete ha llegado, entonces el paquete se pierde.

Una de las primeras mejoras que generalmente se hacen al algoritmo es verificar que el acuse de recibo sea realmente el ack apropiado y no solo un eco enviado por el enrutador o por interferencia cruzada de señal o por un error de software. La solución es implementar un bit de alternancia. El paquete de datos se transmite con el bit de alternancia establecido en un valor y el paquete de confirmación necesita responder con el valor apropiado (generalmente el mismo valor). Si el bit de alternancia es incorrecto, entonces significa que el paquete de reconocimiento no coincide con el último paquete de datos, lo que implica que coincide con el paquete de datos anterior. Esto implica que el último paquete de datos no ha sido reconocido, lo que significa que algo realmente salió mal y el paquete debe retransmitirse hasta que se reciba la confirmación correcta.

 TX RX \ data[0] `-----------------------------> ack[0] / <-----------------------------' \ data[1] `-----------------------------> ack[0] / <-----------------------------' ack mismatch! \ data[1] retransmit `-----------------------------> 

Varios protocolos del mundo real utilizan esta técnica, incluida la mayoría de los protocolos utilizados para controlar equipos industriales y robots.

El siguiente paso es en realidad una expansión de la idea anterior. En lugar de enviar solo un poco por qué no enviar un número. De esa manera, puede hacer coincidir el acuse de recibo con el paquete de datos y detectar con mayor precisión qué paquete se perdió y necesita retransmisión. Esta técnica se suele denominar técnica de ventana deslizante porque, en algún punto, el número se da vuelta y vuelve a cero. Y así, el número máximo de paquetes que puede transmitir antes de que no pueda detectar la pérdida de paquetes es el tamaño de la ventana deslizante.

La gran ventaja de la técnica de la ventana deslizante es que puede enviar muchos paquetes de datos sin esperar el acuse de recibo. Esto mejora significativamente el rendimiento:

  \ data[1] `-----------------------------> \ data[2] `-----------------------------> \ data[3] `-----------------------------> ack[1] / <-----------------------------' ack[2] / <-----------------------------' \ data[4] `-----------------------------> \ data[5] `-----------------------------> ack[3] / <-----------------------------' ack[5] / <-----------------------------' ack[4] missing! . . timeout . \ data[4] retransmit `-----------------------------> 

Así que lo anterior es un breve resumen de la técnica básica para detectar la pérdida de paquetes. Eso es lo que necesita implementar si desea que todos sus paquetes UDP lleguen a su destino.

Sin embargo, debes saber que TCP ya implementa esto, así que deberías usar TCP si no quieres reinventar la rueda. UDP se creó porque en algunos casos la pérdida de paquetes está bien (piense en la transmisión de audio / video).

De wikipedia

UDP es adecuado para fines en los que la verificación y corrección de errores no es necesaria o se realiza en la aplicación, evitando la sobrecarga de dicho procesamiento en el nivel de interfaz de red. Las aplicaciones sensibles al tiempo a menudo usan UDP porque la eliminación de paquetes es preferible a la espera de paquetes retrasados, lo que puede no ser una opción en un sistema en tiempo real. [2] Si se necesitan recursos de corrección de errores en el nivel de la interfaz de red, una aplicación puede usar el Protocolo de Control de Transmisión (TCP) o el Protocolo de Transmisión de Control de Corriente (SCTP) que están diseñados para este propósito.

Básicamente use TCP si le importa, si los paquetes / mensajes llegan allí. De lo contrario, reinvente TCP usando UDP en el nivel de aplicación.

No es posible garantizar la entrega de un paquete UDP específico en CUALQUIER plataforma, no solo node.js. Si lo que busca es un mecanismo de entrega confiable basado en UDP, busque algo como e-net o busque un UDP confiable.

EDITAR: o utilizar TCP.

UDP es un protocolo sin entrega garantizada. Si desea garantizar, debe implementar algún protocolo sobre UDP.