Red de conocimiento informático - Material del sitio web - Cómo implementar un protocolo UDP personalizado y confiable - Reimprimir

Cómo implementar un protocolo UDP personalizado y confiable - Reimprimir

¿Por qué necesitamos UDP confiable cuando ya tenemos TCP?

TCP es una transmisión de confiabilidad obligatoria. Se basa en el protocolo IP y permite al remitente retransmitir todos los datos con regularidad y permitir al receptor ordenar todos los datos. Hay muchos otros mecanismos para habilitar la transmisión del remitente. datos que debe recibir el receptor. Pero en aplicaciones prácticas, no necesitamos una confiabilidad tan obstinada.

Para los juegos FPS, este tipo de requisito de puntualidad es muy alto. En el juego, los jugadores están más preocupados por los resultados de sus disparos y por la supervivencia del personaje cuando se lanza una granada. asesinado, esta granada es un mensaje que debe recibirse, mientras que otros jugadores que no murieron solo necesitan ver la animación o el sonido de la granada explotando. Estos últimos están más preocupados por si sus balas actuales fueron disparadas en la cabeza. No queremos retrasar la confirmación del resultado de dispararle al jugador porque el mensaje de la granada está en cola para su retransmisión, lo que sería insoportable para TCP.

Veamos una imagen:

En las tres dimensiones de eficiencia de transmisión, costo de transmisión y confiabilidad, TCP se ubica en el extremo izquierdo y tiene la mayor confiabilidad, pero el costo de transmisión También es muy alto, pero no tan eficiente como UDP, que se encuentra en el extremo derecho. Solo tiene eficiencia de transmisión pero no puede garantizar la confiabilidad y el costo de transmisión también es bajo. Si necesitamos llegar a un acuerdo en algún lugar alrededor del hexágono, aquí es cuando el transporte confiable UDP (es decir, RUDP) entra en escena.

¿Cómo funciona?

En primer lugar, para garantizar la confiabilidad, debemos agregar un temporizador de retransmisión al enviar datos para garantizar que los datos perdidos se retransmitan. El temporizador de retransmisión puede enviar datos de retransmisión regularmente a través de devoluciones de llamada y también admite la extracción de datos recibidos por ACK del temporizador.

Ahora que tienes un temporizador de retransmisión, ¿cuánto tiempo debes configurar el tiempo de espera para cada vez que envías datos? El método más simple es establecer un tiempo de retransmisión fijo y el método más razonable es establecer un tiempo razonable diferente (rto) para cada enlace de transmisión. Para encontrar el tiempo rto, necesitamos obtener el tiempo de confirmación de cada paquete de datos enviado, es decir, el tiempo rtt, que es el intervalo de tiempo entre el envío de los datos y la recepción de la confirmación ACK. Con referencia a la estrategia de implementación de TCP, podemos registrar el tiempo de envío de cada mensaje. Cuando se recibe una confirmación ACK, el tiempo en este momento se resta del tiempo de envío registrado para obtener el tiempo rtt. Pero hay un problema con esto. Cuando se produce una retransmisión de datos y se recibe un ACK, es imposible determinar si el ACK es una confirmación de los datos de transmisión inicial o una confirmación de los datos de retransmisión. En este momento, el rtt medido. Sólo se puede renunciar al momento de la retransmisión de datos. Entonces, hay una segunda estrategia de cálculo de rtt. Podemos registrar el tiempo de envío en el encabezado de datos y enviarlo. Después de que el extremo receptor confirme que se envió el ACK, copiará la marca de tiempo junto con el retorno del ACK. El extremo emisor recibe la confirmación ACK. La hora en que se envían los datos de confirmación se puede conocer con precisión, por lo que se puede calcular el tiempo rtt. Con el tiempo rtt, podemos calcular el tiempo rto de acuerdo con el método TCP estándar (Explicación detallada de CP/TPxian Volumen 1, P465).

Cuando se recibe una confirmación ACK, debemos eliminar la confirmación del temporizador.

Para mejorar la utilización del enlace de red, el receptor no puede enviar una confirmación ACK inmediatamente cada vez que recibe datos. ¿Por qué? Cuanto menor sea la cantidad de datos transmitidos, mayor será la proporción de encabezados de control, y los paquetes de datos que transportan solo un ACK que vuelan por toda la red harán que los enrutadores se pongan en cola. Puede consultar la estrategia de implementación de TCP aquí.

Uno es un ACK retrasado, es decir, el extremo receptor personaliza un TIEMPO PENDIENTE para el mensaje recibido. Cuando expira, todos los ACK se combinarán y enviarán dentro de este tiempo. El otro es un ACK complementario, que es el TIEMPO PENDIENTE. todavía, pero resulta que tiene datos para enviar al otro extremo, por lo que envía el ACK junto con el paquete de datos. Dado que el ACK enviado por el receptor no es instantáneo, el error de cálculo resultante debe tenerse en cuenta en el cálculo del RTT anterior.

Algunos estudiantes quieren preguntar, usted ha estado diciendo durante mucho tiempo que UDP es confiable, ¿no tiene TCP también la misma estrategia? Entonces, de lo que voy a hablar a continuación no es lo mismo que TCP.

Solo hablamos de la estrategia de envío y recepción de un paquete de datos. ¿Cómo enviarlo cuando llega una gran cantidad de datos? No es posible enviar todos los datos a la vez. Por lo tanto, necesitamos una ventana de envío para controlar la cantidad de datos a enviar y sacar el siguiente paquete a enviar cuando se permita el envío (es decir, cuando se recibe un nuevo ACK o se cambia el tamaño de la ventana de envío). La implementación aquí es diferente de TCP, que agrupa todos los datos en el búfer y luego controla el flujo de envío de datos moviendo la ventana deslizante. En lugar de utilizar un formulario deslizante, coloco todos los paquetes de datos en una cola de permisos y ajusto el orden de envío de acuerdo con las reglas de envío de dos paquetes de permisos de alto nivel y un paquete de bajo nivel. El formulario de envío solo envía datos en la máquina. paquetes cuando se pueden enviar. Luego obtenga el siguiente paquete de datos de la cola de permisos. El formulario de envío es responsable de almacenar en caché y confirmar los datos enviados, y la cola de permisos es responsable de determinar la prioridad de los datos enviados.

Para el extremo receptor, también se necesita una cola de recepción para organizar los paquetes de datos recibidos, donde podemos implementar múltiples estrategias de cola según sea necesario. Si queremos obtener el efecto de TCP, los datos están ordenados y confiables, entonces debemos enviar una confirmación ACK a todos los paquetes de datos que llegan y ponerlos en cola. Solo el paquete de datos anterior se pondrá en cola y los datos se pueden devolver a la capa superior. sin perturbarlo; si solo se implementa la confiabilidad y no se requiere clasificación, después de recibir un paquete de datos, se puede devolver directamente a la capa superior, pero se debe enviar una confirmación ACK. Si solo necesita clasificación y no necesita confiabilidad, puede registrar el número de secuencia máximo de paquetes de datos recibidos hasta el momento. Los paquetes de datos mayores que este número de secuencia se devuelven a la capa superior y los paquetes de datos más pequeños que este número de secuencia se descartan directamente. sin enviar ACK, porque El remitente tampoco retransmitirá los datos. Estos son tres tipos diferentes de transmisión confiable.

Hemos dicho mucho antes que el paquete de datos lleva tanto la marca de tiempo como el ACK de confirmación. Necesitamos enviar los datos hacia abajo y agregar nuestro propio encabezado de protocolo a la capa superior para permitir que ambos extremos identifiquen el. Mensaje necesario, aquí podemos usar diferentes combinaciones de etiquetas de control para implementar encabezados de protocolo de longitud variable, utilizando efectivamente paquetes de datos para transmitir la cantidad de datos.

Entre ellos, Flag es obligatorio, ocupa una longitud de 4 bytes y utiliza un bit para identificar si se debe transportar cada bloque posterior, lo que se puede lograr mediante una secuencia binaria manual.

Ahora, para una conexión de transmisión, tenemos un mecanismo de retransmisión, un mecanismo de reconocimiento, encapsulación de encabezado de protocolo, control de transmisión y recepción, pero la red es un tráfico público, ¿cómo cumplimos con las reglas de tráfico? ¿Cómo utilizar eficazmente el ancho de banda de la red sin causar congestión? Esta es la introducción al algoritmo de control de congestión. Actualmente estoy usando BBR y TCP CUBIC aún no se ha implementado. ¿Por qué utilizar el algoritmo BBR? Es una larga historia sobre un niño sin madre. En pocas palabras, el algoritmo CUBIC ordinario determina la congestión de la red detectando la pérdida de paquetes y luego controla la cantidad de datos transmitidos por la red controlando el tamaño del formulario enviado. Piense en lo que está sucediendo en la red:

El algoritmo CUBIC detecta la pérdida de paquetes en la fase 3 y comienza a reducir el tamaño del formulario de envío para reducir la cantidad de datos transmitidos en la red y digerir la cola del enrutador. ¡Pero ya es demasiado tarde! Antes de que se produzca la pérdida de paquetes, el enlace ya está bajo presión de paquetes y el tiempo de RTT para enviar datos ya es muy lento.

¿Cuándo es máxima la utilización del enlace? Es decir, el tiempo de RTT es mínimo cuando está a punto de ocurrir una situación de cola en el enrutador de segundo nivel, pero ya hay suficientes datos volando en el enlace. Otro problema con el algoritmo CUBIC es que la única variable de salida que controla es el tamaño de la ventana de envío. Cuando la ventana de envío aumenta y llegan datos de la capa de aplicación, enviará todos los datos que pueda enviar en una ráfaga. En las intersecciones en la vida real, todos respetarán las reglas de tránsito y se asegurarán de que algunos vehículos puedan pasar en cada intersección a través del control del semáforo. Sin embargo, en el mundo en línea, todo se vuelve irrazonable cuando hay muchos automóviles en esta intersección. No es correcto que todos los coches vayan uno tras otro, independientemente de si hay otros coches esperando en la intersección. Por lo tanto, el algoritmo BBR no solo necesita controlar el tamaño del formulario de envío para controlar la cantidad de datos enviados, sino que también calcula la velocidad de envío de datos a través del tiempo RTT y la cantidad de datos transmitidos, y logra una cierta velocidad de envío por controlar el intervalo de tiempo de envío del flujo de datos. Cómo implementar específicamente el algoritmo BBR es otra discusión extensa y no se detallará en este artículo.

En este punto, básicamente hemos completado los mecanismos de confiabilidad y eficiencia de transmisión. Ahora hablemos del establecimiento de transmisión y conexión. El establecimiento de la transmisión no se refiere al protocolo de enlace de tres vías de TCP. Según la simplicidad de UDP, siempre que el remitente envíe datos, el receptor puede recibirlos. Una vez establecida la conexión, el tiempo de espera del remitente se agota. No se reciben datos. Debido a que nuestro protocolo se implementa en la capa de aplicación, no se puede enviar ningún RST al otro extremo cuando no se inicia ningún proceso. Cuando se desconecta la conexión, básicamente nos referimos a la implementación de cuatro ondas de TCP y continuamos conservando el estado TIME_WAIT para garantizar que los paquetes de la conexión anterior en la red no se envíen a la conexión actual.

El mecanismo de implementación general finalmente está terminado. También hay algunos otros detalles, como la identificación del número de secuencia del paquete, el primer número de secuencia aleatorio, la cola de flujo y la implementación del ritmo. Sin embargo, la implementación central confiable es básicamente Eso es todo. , dibujemos un diagrama de flujo de datos:

Hay un proceso de filtrado en el socket, que es una cadena de filtrado de responsabilidad. Esta es una cadena de responsabilidad de filtro. Todos los datos enviados y recibidos deben pasar por esta cadena de responsabilidad de filtro. Puede comprimir y cifrar el cuerpo del paquete de datos transmitido. Aquí he implementado la compresión y el filtrado de los datos transmitidos, un hilo adicional. filtro de notificación y filtro de división de paquetes grandes. Al administrar todos los módulos de filtro a través de una lista doblemente vinculada, puede incorporar fácilmente procesos de filtro adicionales, donde también puede implementar algunos reenvíos de disyuntores y otros filtros relacionados con la gobernanza del servicio.