Red de conocimiento informático - Problemas con los teléfonos móviles - Contenido relacionado con TCP.

Contenido relacionado con TCP.

Índice de contenidos:

También solía pensar que TCP era algo de muy bajo nivel que nunca necesitaría entender. Si bien esto es cierto, en la vida real aún puedes encontrar errores relacionados con el algoritmo TCP, por lo que es fundamental saber algo sobre TCP. (Este artículo también se puede extender a las llamadas al sistema, los sistemas operativos, etc. también son importantes, lo que se aplica a muchos aspectos)

El siguiente es un artículo breve que recomendamos: Todos deberían entender TCP

Para comunicarse utilizando el protocolo TCP, primero debe establecer una conexión TCP y luego mantener algunas estructuras de datos requeridas para la conexión en el kernel, como el estado de la conexión, la cantidad de estructuras de datos requeridas y la cantidad. de estructuras de datos que deben mantenerse en el kernel. Ambas partes que se comunican mediante el protocolo TCP primero deben establecer una conexión TCP y mantener las estructuras de datos requeridas para la conexión en el kernel, como el estado de la conexión, los buffers de lectura y escritura, los temporizadores, etc. Cuando finaliza la comunicación, ambas partes deben cerrar la conexión para liberar estos datos del núcleo. Los servicios TCP se basan en flujos y el flujo de tráfico de un extremo al otro es constante y puede escribirse byte a byte en el lado del remitente y leer byte a byte en el lado del receptor sin necesidad de fragmentación.

Notas:

Estado de TCP (11):

Por ejemplo:

Los anteriores son los cambios de estado de los tres protocolos de enlace TCP

Los siguientes son los cambios de estado de los cuatro protocolos de enlace TCP

El servidor ingresa al estado ESCUCHAR escuchando la llamada del sistema y espera pasivamente a que el cliente se conecte, también conocido como pasivo abierto. Una vez que el servidor escucha una solicitud SYN, coloca la conexión en la cola de espera del kernel y envía un ACK con SYN al cliente en el estado SYN_RECVD. Si el servidor recibe el ACK devuelto por el cliente, entrará en el estado ESTABLECIDO. En este estado, ambas partes de la conexión pueden realizar una transmisión de datos full-duplex.

Cuando el cliente cierra activamente la conexión, el servidor recibirá el mensaje FIN y hará que la conexión entre en el estado CLOSE_WAIT devolviendo ACK. Este estado significa: Esperando a que la aplicación del servidor cierre la conexión. Por lo general, después de que el servidor detecta que el cliente está cerrando la conexión, enviará inmediatamente un FIN al cliente, transferirá la conexión al estado LAST_ACK, esperará la última confirmación del cliente del último segmento del mensaje final FIN y luego cerrará el conexión después de que se complete la confirmación, cerrando así la conexión.

El cliente inicia una conexión con el servidor a través de la llamada al sistema connect. Esta llamada al sistema primero envía un SYN al servidor, poniendo la conexión en el estado SYN_SENT.

Hay dos razones por las que falla la llamada de conexión: 1. El puerto de destino no existe (ningún proceso está escuchando en el puerto) y está ocupado por una conexión en el estado TIME_WAIT (ver más adelante). 2. La conexión se agota y el servidor no recibe un ACK dentro del período de tiempo de espera.

Si la llamada de conexión falla, la conexión se devolverá al servidor.

Cuando el cliente realiza un apagado activo, enviará un FIN al servidor y la conexión entrará en el estado TIME_WAIT_1. Si se recibe un ACK del servidor, la conexión entrará en el estado TIME_WAIT_2. En este punto, el servidor está en el estado CLOSE_WAIT y, durante este par de estados, puede ocurrir el cierre de la oficina (ver más abajo). Si el servidor envía un FIN para cerrar la conexión, el cliente enviará un ACK para confirmar e ingresar al estado TIME_WAIT.

El control de flujo se utiliza para controlar la velocidad de envío del remitente para garantizar que el receptor lo reciba a tiempo.

El campo de ventana en el mensaje de confirmación enviado por el receptor se puede utilizar para controlar el tamaño de la ventana del remitente, lo que afectará la velocidad de envío del remitente. Establecer el campo de la ventana en 0 evitará que el remitente envíe datos.

Si la red está congestionada, los paquetes se perderán y el remitente continuará retransmitiendo estos paquetes, lo que provocará una congestión más grave. Por lo tanto, cuando se produce congestión, se debe controlar la tarifa del remitente. Esto es similar al control de flujo, pero desde un punto de partida diferente. El propósito del control de flujo es permitir que el receptor reciba mensajes de manera oportuna, mientras que el propósito del control de congestión es reducir la congestión en toda la red.

TCP utiliza principalmente cuatro algoritmos para el control de la congestión: inicio lento, evitación de la congestión, retransmisión rápida y recuperación rápida.

Existen muchos métodos de implementación en Linux, como el algoritmo reno, el algoritmo vegas y el algoritmo cúbico.

El remitente necesita mantener una variable de estado llamada ventana de congestión (cwnd). Tenga en cuenta la diferencia entre la ventana de congestión y la ventana del remitente: la ventana de congestión es solo una variable de estado, es la ventana del remitente la que realmente determina cuántos datos puede enviar el remitente.

Para facilitar la discusión, haga las siguientes suposiciones:

Al comenzar a enviar, establezca cwnd = 1, el remitente solo puede enviar 1 segmento de información al recibir la confirmación; Duplique el cwnd para que el remitente pueda enviar el siguiente número de segmentos: 2, 4, 8, etc...

Tenga en cuenta que el inicio lento aumenta el cwnd en uno cada ronda, esto hará que cwnd crecen muy rápido, lo que hace que la tasa de envío del remitente crezca demasiado rápido, aumentando la posibilidad de congestión de la red. Establezca el umbral de inicio lento ssthresh, ingrese al estado para evitar la congestión cuando cwnd gt = ssthresh y solo aumente cwnd en 1 en cada ronda.

Si se agota el tiempo de espera, haga ssthresh = cwnd/2 y realice un inicio lento nuevamente.

En el lado receptor, cada segmento recibido debe acusar recibo del último segmento ordenado recibido. Por ejemplo, se han recibido M1 y M2, y en este momento se ha recibido M4, se debe enviar un acuse de recibo de M2.

En el lado del remitente, si se reciben tres acuses de recibo duplicados, se sabe que el siguiente segmento de información se pierde y se realizará una retransmisión rápida para retransmitir inmediatamente el siguiente segmento de información. Por ejemplo, si se reciben tres M2, M3 se pierde y M3 se retransmite inmediatamente.

En este caso, sólo se pierde un dato, no la congestión de la red. Por lo tanto, realice una recuperación rápida para que ssthresh = cwnd/2, cwnd = ssthresh. Tenga en cuenta que la prevención de congestión se ingresa directamente en este momento.

Los términos "rápido" y "lento" para un inicio lento y una recuperación rápida se refieren a la configuración de cwnd, no a la tasa de crecimiento de cwnd. El inicio lento cwnd se establece en 1 y el cwnd de recuperación rápida se establece en ssthresh.

?Cada mensaje TCP del remitente debe ser respondido por el receptor para que la transmisión sea exitosa.

TCP mantiene un temporizador de retransmisión para cada segmento TCP.

?El remitente inicia el temporizador después de enviar el segmento TCP. Si no se recibe respuesta dentro del período de tiempo, el remitente reenvía el segmento y reinicia el temporizador.

?Debido a que los segmentos de mensajes TCP finalmente aparecen en forma de datagramas IP en la capa de red, y los datagramas IP pueden estar desordenados o repetidos cuando llegan al extremo receptor, el protocolo TCP se reorganizará y organizará. ellos Paquetes TCP entrantes para garantizar el orden correcto.

Los datos de la aplicación transportados por los segmentos de paquetes TCP se dividen en dos tipos según la longitud: datos interactivos y datos fragmentados.

En cuanto a qué son los paquetes fijos y los problemas de segmentación de paquetes, yo lo haría. Me gustaría enumerar primero dos escenarios de aplicación simples:

Para el primer escenario, el flujo de procesamiento del lado del servidor puede ser el siguiente: cuando la conexión entre el cliente y el servidor se establece exitosamente, el servidor lee continuamente el datos enviados por el cliente de datos, cuando se desconecta la conexión entre el cliente y el servidor, el servidor sabe que un mensaje ha sido leído y luego decodificado y posteriormente procesado.........Para el segundo caso, si usted. Si sigue la misma lógica de procesamiento anterior, entonces surgirán problemas. Echemos un vistazo a lo que puede suceder cuando los dos mensajes enviados por el cliente se entregan al servidor en el segundo caso:

El primer caso. :

p>

El servidor lee dos paquetes de datos. El primer paquete de datos contiene la información completa del primer mensaje enviado por el cliente y el segundo paquete de datos contiene el segundo mensaje enviado por el cliente. entonces esta situación es más fácil de manejar: el servidor solo necesita leer del búfer de red. Lee la información completa del primer mensaje por primera vez, la consume y luego lee el segundo mensaje completo. mensaje en la zona y consumirlo.

La segunda situación:

Tan pronto como se inicia el servidor, leerá un paquete de datos. Este paquete de datos contiene la información completa de los dos mensajes enviados por el cliente. En este momento, el servidor implementado según la lógica anterior quedará cegado, porque el servidor no sabe dónde termina el primer mensaje y comienza el segundo. Este es en realidad el caso de los paquetes adhesivos TCP.

La tercera situación:

El servidor recibe dos paquetes de datos. El primer paquete de datos solo contiene parte del primer mensaje, y la segunda mitad del primer mensaje y el segundo mensaje. ambos en el segundo paquete, o el primer paquete contiene el primer mensaje y parte del segundo mensaje, y el segundo paquete contiene el resto del segundo mensaje. Esta situación en realidad está enviando una división de TCP, porque un mensaje se dividirá en dos paquetes para enviar, y la lógica del servidor anterior tampoco es adecuada para esta situación.

Sabemos que TCP es un método de transmisión de datos fluido y que la unidad de transmisión más pequeña es un segmento de mensaje. El encabezado TCP tiene un bit identificador de opciones. El identificador comúnmente utilizado es mss (tamaño máximo de segmento), lo que significa que la capa de conexión tiene un límite máximo de MTU (unidad de transmisión máxima) para los datos transmitidos cada vez. Unidad de transmisión máxima), generalmente 1500 bits. Si excede esta cantidad, se dividirá en múltiples segmentos de mensaje. mss es el tamaño de los datos transmitidos individualmente después del límite máximo menos el encabezado TCP, que generalmente es 1460 bits. Convertido a bytes, son más de 180 bytes.

Para mejorar el rendimiento de TCP, el remitente enviará los datos que se enviarán al búfer, esperará a que el búfer esté lleno y luego enviará los datos del búfer al receptor. Asimismo, el receptor también tiene un mecanismo similar a un búfer para recibir datos.

Las razones principales para los paquetes fijos TCP y el descomprimido son las siguientes:

Como sabemos que TCP es un flujo de datos ilimitado y el protocolo en sí no puede evitar los paquetes fijos, se produce el descomprimido. por lo que solo podemos controlarlo en la capa de aplicación del protocolo de datos.