2009-10-03 13 views
8

Tenemos un sistema (construido en C) en su lugar que realiza la comunicación a través de UDP. Recientemente, hemos encontrado la necesidad de garantizar la entrega de paquetes. Mi pregunta es: ¿cuáles serían las adiciones mínimas a un sistema basado en UDP para garantizar la entrega usando paquetes de ack? Además, idealmente sin tener que manipular los encabezados del paquete. Tenemos control de nivel de aplicación sobre los paquetes, incluidos los números de secuencia y las banderas ack/nack. Me pregunto si esta es una causa perdida y cualquier cosa que intentemos hacer será básicamente una versión defectuosa y rota de TCP. Básicamente, hay una mejora minimalista que podemos hacer para lograr una entrega garantizada (no necesitamos muchas características de TCP como control de congestión, etc.). ¡Gracias!implementando ack sobre UDP?

+1

¿Estás seguro de que vale la pena? Simplemente usando una tecnología probada vs. un sistema homebrew. ¿Está claro el beneficio de rendimiento o simplemente optimiza prematuramente? –

+0

El sistema es en tiempo real y ya se ajusta a la especificación que requiere UDP. –

Respuesta

5

Tome un vistazo a los Capítulos 8 y 20 de Steven UNIX Network Programming, volume 1. Él cubre una cantidad de enfoques diferentes. La sección 20.5 "Agregar confiabilidad a una aplicación UDP" es probablemente lo más interesante para usted.

+0

+1 para una gran referencia. Cuando anteriormente hacía algo similar para una tarea de programación, esa sección era excelente. – mrduclaw

4

Tengo una pregunta ejecutando here que está recogiendo respuestas a "Qué se debe usar cuando se necesita UDP confiable". Las respuestas son posiblemente mucho más de lo que desea o necesita, pero es posible que pueda ver algunos de los protocolos que se han creado en UDP y obtener solo la parte de ACK que necesita.

Según mi trabajo con el protocolo ENet (un protocolo UDP confiable), espero que necesite un número de secuencia en cada datagrama UDP, una forma de enviar un ACK para los datagramas que ha recibido, una forma de mantenerlo de los datagramas que has enviado hasta que recibas un ACK o el tiempo de espera y una forma de sincronizar el reenvío de los datagramas para los que aún no has recibido un ACK ... También agregaría un tiempo de espera total para cuando decidas que nunca va a entregar un datagrama en particular y, supongo, una devolución de llamada a su capa de aplicación para informarle de esta falla en la entrega ...

8

TCP entrelaza 3 servicios que podrían ser relevantes (está bien TCP hace una mucho más, pero solo voy a hablar de 3.)

  1. Dentro de la orden de entrega
  2. Entrega confiable
  3. Control de flujo

Usted acaba de decir que no es necesario el control de flujo, por lo que ni siquiera tendrá que hacer frente (cómo se anuncie un tamaño de ventana, etc. bueno, excepto que probablemente necesite una ventana. lo haré.)

Usted dijo que necesita una entrega confiable. Eso no es demasiado difícil: utiliza ACK para mostrar que el emisor ha recibido un paquete. entrega confiable básica se parece a:

  1. remitente envía el paquete
  2. receptor recibe el paquete y, a continuación, envía un acuse de recibo
  3. Si el remitente no recibe un acuse de recibo (por medio de un temporizador), se vuelve a enviar el paquete.

Esos tres pasos no se ocupan de estos temas:

  1. ¿Qué pasa si el ACK se pierde?
  2. ¿Qué pasa si los paquetes llegan fuera de servicio?

Por lo tanto, para su aplicación, dijo que solo necesitaba una entrega confiable, pero no dijo nada acerca de necesitarlas en orden. Esto afectará la forma en que implementa su protocolo.

(ejemplo en el que en el orden no importa:.. Va a copiar los registros de empleados de un ordenador a otro no importa si el registro de Alice se recibe antes de Bob, siempre y cuando ambos llegar)

Por lo tanto, suponiendo que solo necesita confianza (ya que eso es lo que dijo en su publicación), podría lograr esto de varias maneras.

Su remitente puede realizar un seguimiento de los paquetes no reconocidos. Entonces, si envía # 3, 4, 5 y 6, y no recibe un ACK para 3 y 4, entonces el remitente sabe que necesita retransmitir. (Aunque el remitente no sabe si los paquetes 3 y 4 fueron muchos, o si se perdieron sus ACK. De cualquier manera, tenemos que retransmitir).

Pero entonces su remitente podría hacer ACK acumulativos, por lo que en el ejemplo anterior , solo marcaría # 6 si hubiera recibido 3, 4 y 5. Esto significa que el receptor eliminaría el paquete 6 si no hubiera recibido los anteriores. Si su red es muy confiable, esta podría no ser una mala opción.

Los protocolos descritos anteriormente, sin embargo, tienen una ventana, es decir, ¿cuántos paquetes envía el remitente a la vez? Lo que significa que necesita algún tipo de ventana, pero no para controlar el flujo. ¿Cómo transmites los tamaños de ventana?

Puede hacerlo sin ventana, ya sea manteniendo constante el tamaño de la ventana o haciendo algo así como "detener y esperar". El primero podría ser una mejor opción.

De todos modos, no he respondido directamente a su pregunta, pero espero haber señalado algunas de las cosas que vale la pena considerar al diseñar esto. ¡La tarea de tener una "transferencia confiable" sin partes de control de flujo (como ventanas) y sin tener en cuenta el orden es difícil! (¡Déjeme saber si debo dar más detalles sobre algunas de estas cosas!)

¡Buena suerte!

0

La mejor forma de implementar ack es hacerlo en la capa de aplicación. CoAP es un ejemplo de protocolo de aplicación que se ejecuta en udp pero proporciona una transferencia de datos confiable. Mantiene un ID de mensaje para todos los mensajes confirmables (CON) y envía un receptor que envía un paquete de respuesta con el mismo ID de mensaje. Todos los campos de Id. De respuesta y de mensaje se mantienen en la parte de la capa de aplicación. Entonces, si el emisor no recibe un paquete Ack con el id del mensaje enviado por él, re transmite ese paquete. El desarrollador de aplicaciones puede modificar el protocolo para satisfacer las necesidades requeridas para una transferencia de datos confiable.