Cómo responder al protocolo de enlace de tres vías TCP y la onda de cuatro veces con muchas preguntas de entrevista

Menos código, más cabello

Tres apretones de manos para establecer un enlace, cuatro ondas para romper el enlace. Esta pregunta es muy clásica y al entrevistador le gusta hacerla.

No es exagerado decir que cuando el tío Long reclutó entrevistas en la escuela, todas las compañías hicieron preguntas sobre el apretón de manos de tres vías y la ola de cuatro vías.

La importancia de este problema se ha dado cuenta. No hable tonterías, el siguiente paso es escuchar los arreglos claros hechos por tío Long para usted.

Primero dibuje una imagen para ver el proceso general de establecer y desconectar TCP.

TCP apretón de manos tres veces y ondas cuatro veces
TCP apretón de manos tres veces y ondas cuatro veces

Después de leer esta imagen, creo que eres inteligente y tienes un control básico sobre tres apretones de manos y cuatro titubeos. Sin embargo, los detalles en el interior definitivamente serán un poco oxidados o vagos, y luego la esencia del problema se revelará uno por uno.

Antes de explicar, primero mire lo básico para hacer un presagio.

Transferencia de estado TCP explicada

Estado Descripción
CERRADO Estado bloqueado o cerrado, lo que indica que el host no está transmitiendo o estableciendo actualmente un enlace
ESCUCHA Supervisar el estado, lo que indica que el servidor está listo para esperar el establecimiento de un enlace de transmisión
SYN RECV Recibió la primera solicitud de transmisión sin confirmación.
SYN ENVIADO Después de enviar el primer mensaje SYN, esperando la confirmación
ESTABLECIDO Ingrese a la etapa de transmisión de datos después de que el enlace se establezca normalmente
FIN WAIT1 Ingrese este estado después de enviar activamente el primer mensaje FIN
FIN WAIT2 Ha recibido la señal de confirmación del primer FIN, esperando que la otra parte envíe una solicitud de cierre
ESPERA TEMPORIZADA Complete el cierre de enlace bidireccional y espere a que desaparezca el paquete
CLAUSURA Cuando ambas partes cierran la solicitud al mismo tiempo, esperando que la otra parte confirme
CERRAR ESPERAR Reciba la solicitud de apagado de la otra parte y confirme para ingresar a este estado
ÚLTIMO ACUSE Espere el último mensaje para confirmar el apagado.

Mira el formato del mensaje TCP nuevamente

Formato de mensaje TCP
Formato de mensaje TCP

El encabezado tiene una longitud fija de 20 bytes, el significado es el siguiente:

  1. Puerto de origen y puerto de destino

2 bytes cada uno, que almacena el número de puerto de origen y el puerto de destino

  1. Seq

Toma 4 bytes, y el rango indicado es el rango de conformación [0 ~ 2 ^ 32]. El número de serie se usa para numerar cada byte de la parte de datos, y el método de numeración es mod 2 ^ 32.

  1. Número de confirmación ack

Toma 4 bytes y el rango también es el rango de enteros sin signo. Utilice el último número de secuencia de bytes de los datos que se me transmitieron en el extremo opuesto, por ejemplo, A se transmite a B 101-500. En este momento, el número de confirmación devuelto por B debe ser menor o igual a 501. El número de confirmación solo se devolverá después de que el segmento B reciba los datos correctamente. En otras palabras, todos los datos antes de que se haya recibido el número de confirmación.

  1. Desplazamiento de datos

Se necesitan 4 bits y los datos están apagados. Muchas personas pueden pensar fácilmente si significa la longitud de los datos, lo cual es incorrecto. El desplazamiento se refiere al desplazamiento desde la posición inicial del TCP a la posición inicial de la parte de datos, es decir, la longitud del encabezado TCP.

  1. Mantener

Ocupa 6 bits. El campo reservado, como su nombre lo indica, es para uso futuro y se establece en 0 de forma predeterminada.

  1. Bit de control URG de emergencia

Ocupe 1 bit, URG = 1, lo que indica que el puntero de emergencia es válido, en este momento los datos tcp se transmiten preferentemente. Es equivalente a un pasaje de emergencia en la vida y se usa en situaciones especiales.

También habrá situaciones especiales en la red, por ejemplo, al enviar un programa largo para ejecutarse en un servidor remoto, en este momento se descubre que el programa tiene un error y necesita ser interrumpido, por lo que ingresamos Ctrl c desde el teclado. En cola en la zona de amortiguamiento, todos sabemos que es un error, y todavía tenemos que hacer cola, me temo que estará fuera de la sartén.

En este momento, se utiliza la transmisión de datos de emergencia y no hay necesidad de hacer cola. ¿Está más en línea con nuestras expectativas interrumpir directamente el programa?

Cabe señalar que incluso cuando la ventana es 0, se pueden enviar datos de emergencia.

Cómo usar el bit de control URG de emergencia, el parámetro indicador de la función de envío en la programación del socket

send(int socket, const void *buffer, size_t length, int flags);

Cuando el parámetro flags pasa la macro MSG_OOB, indica que hay datos urgentes en este momento. MSG_OOB es una macro,

  1. Confirmar ACK

Tarda 1 bit y surte efecto cuando ACK = 1. TCP tiene una regla estricta y rápida de que todos los paquetes de datos transmitidos deben establecer ACK en 1 cuando la conexión se establece con éxito.

  1. Empujar PSH

Tarda 1 bit. Cuando el emisor establece PSH en 1, el paquete de datos se enviará de inmediato y el receptor procesará inmediatamente el paquete con PSH = 1 y lo entregará a la capa de aplicación para su procesamiento. ¿Se siente muy similar a URG, pero todavía hay algunas diferencias?

  • Los dos son similares:

Tanto URG como PSH se utilizan en situaciones de manejo de emergencia para transmitir rápidamente datos de emergencia.

  • La diferencia entre los dos

Cuando URG se establece en 1, para el envío, los "datos fuera de banda" se encapsulan en datagramas que se enviarán junto con los datos del mensaje que se deben enviar en circunstancias normales, eliminando el tiempo de espera en la cola. En el lado de recepción, después de analizar el mensaje, aún debe colocarse en el área de caché después de obtener los datos, y después de estar lleno, se entrega hacia arriba a la capa de aplicación.

Cuando PSH se establece en 1, para el remitente, significa que los datos no necesitan esperar a que se envíe el área del búfer para que esté llena, se encapsula inmediatamente en un mensaje y se envía, eliminando el tiempo de espera para que el búfer alcance el estado completo. En el lado receptor, no hay necesidad de esperar a que el búfer receptor esté lleno y entregarlo directamente a la capa de aplicación.

  1. Restablecer RST

Ocupar 1 bit, cuando RST = 1, TCP liberará activamente el enlace, se utilizarán dos casos.

Cuando se produce un error grave en TCP, liberará activamente la conexión, restablecerá la conexión y transmitirá los datos.

Cuando encuentra paquetes ilegales o se niega a conectarse, establecerá RST en 1.

  1. SYN sincrónico

Ocupe 1 bit, bit de control síncrono, utilizado para sincronizar el número de serie de la transmisión cuando se establece la conexión de transmisión.

Cuando SYN = 1, significa que se trata de una solicitud de conexión o un mensaje de confirmación de conexión.

SYN = 1, ACK = 0, lo que indica que este es un segmento de datos de solicitud de conexión, si la otra parte acepta establecer una conexión, la otra parte devolverá una confirmación de SYN = 1, ACK = 1.

  1. Bit de control FIN

Ocupa 1 bit y se utiliza para liberar una conexión de transmisión.

Cuando FIN = 1, significa que los datos se han transmitido por completo y el remitente no tiene datos para transmitir, solicitando liberar la conexión actual, pero el receptor puede continuar recibiendo los datos que no se han recibido.

FIN = 0, transmisión de datos normal.

  1. Tamaño de la ventana

Ocupa 16 bits, 2 bytes y se utiliza para indicar el tamaño máximo de datos que el remitente puede aceptar.

Esta ventana cambia dinámicamente y se usa para el control de flujo.

  1. Suma de comprobación

16 bits, 2 bytes, utilizados para verificar el encabezado TCP, el pseudo encabezado y los datos.

  1. Puntero de emergencia

Ocupa 16 bits, 2 bytes y se utiliza para registrar la posición del final de los datos de emergencia en el segmento de datos .

Cuando URG = 1, el puntero surte efecto.

  1. Opcional

Las opciones pueden tener hasta 40 bytes de longitud, lo cual es opcional y se puede omitir. Cuando el elemento opcional no existe, la longitud del encabezado TCP es de 20 bytes.

Las opciones pueden incluir opciones de escala de ventana (WSopt), opciones MSS (tamaño máximo de segmento de datos), opciones SACK (reconocimiento selectivo), opciones de marca de tiempo (marca de tiempo), etc.

  1. Datos

La parte de datos TCP son los datos enviados por el programa de aplicación en la capa de aplicación.

El encabezado TCP es el conocimiento básico. Debe comprenderlo para comprender mejor cómo se encapsulan y transmiten los datos TCP, y para operar esos lugares al establecer y desconectar enlaces.

Apretón de manos de tres vías para establecer una conexión

¿Cómo un enlace de tres vías establece una conexión?

Apretón de manos de tres vías para establecer un enlace
Apretón de manos de tres vías para establecer un enlace

Se puede ver claramente en la figura que durante el apretón de manos de tres vías, estoy explicando claramente el proceso y, por cierto, los puntos de conocimiento que se preguntan fácilmente en cada proceso.

Adopte el modo C / S para explicar, suponga que C end inicia la solicitud de transmisión.

Antes de enviar una solicitud de establecimiento de enlace, el terminal C mantiene el estado CERRADO, y el terminal S está inicialmente en el estado CERRADO. Cuando se ejecuta la función de escucha, el socket pasa al estado de escucha pasiva .

El llamado monitoreo pasivo significa que cuando no hay una solicitud del cliente, el socket está en el estado de "suspensión". Solo cuando se recibe la solicitud del cliente, el socket se "despertará" para responder a la solicitud.

La primera vez: el terminal C envía un mensaje de solicitud con SYN = 1, en este momento el terminal C ingresa al estado SYN SENT, esperando que el servidor confirme.

¿Qué sucede si el paquete se pierde y no se puede enviar al igual en este momento?

Después de enviar un mensaje, el terminal C iniciará un temporizador. Después del tiempo de espera, si no se recibe confirmación del terminal S, se enviará nuevamente una solicitud SYN. ​​El tiempo para cada intento se duplicará la primera vez. Si el tiempo total total del intento es 75 Segundos, el establecimiento del enlace falló esta vez.

La segunda vez: después de que el extremo S recibe el mensaje SYN (solicitud de establecimiento de enlace) enviado por el extremo C, el extremo S debe devolver el número de confirmación y enviar un mensaje SYN al mismo tiempo, luego ingrese el estado RCVD SYN.

¿Por qué enviar mensajes SYN juntos?

TCP es comunicación full-duplex. El protocolo estipula que al recibir una solicitud de establecimiento de enlace, debe devolver el número de serie y establecer un enlace de comunicación local a igual. Esto también se llama mecanismo de respuesta superpuesta.

¿Qué pasa si se pierde el segundo mensaje?

Después de enviar el mensaje ACK + SYN, se iniciará un temporizador. Si el ACK no se recibe después del tiempo de espera, se enviará nuevamente y se realizarán múltiples intentos. El período de tiempo de espera todavía se duplica cada vez, y se puede establecer el número de reintentos.

Modificar /proc/sys/net/ipv4/tcp_synack_retriesel valor

image-20200412205846062

La tercera vez: el terminal C recibe el mensaje ACK + SYN enviado por el terminal S y necesita devolver un mensaje de respuesta ACK. En este momento, la conexión ingresará a la cola semi-conectada. Cuando el terminal S recibe el ACK, un Se establece el enlace TCP full-duplex, y ambas partes entran en el estado ESTABLECIDO.

Aquí hay un método de ataque común. El atacante falsifica una solicitud SYN y la envía al servidor. Después de que el servidor responde, no recibirá la confirmación ACK del lado C. El servidor volverá a intentarlo continuamente. Por defecto, volverá a intentarlo cinco veces.

En este momento, el servidor mantendrá todos los recursos de este enlace. Si hay una gran cantidad de tales solicitudes, los recursos del servidor se agotarán.

Este es un ataque de DOS.

¿Qué pasa si se pierde el tercer mensaje?

El terminal S iniciará un temporizador después de enviar el mensaje ACK + SYN, y confirmará que se perdió antes de recibir el ACK después del disparo del tiempo de espera, e intentará enviar nuevamente.

Todos los estados en esto deben ser entendidos, y al entrevistador también le encanta preguntar sobre la transición de estado anterior.

El tío Long también se reunió con un entrevistador y me preguntó si usé la programación de socket. P. ¿Qué funciones de socket he usado?

Código de programación del zócalo del lado C

//C端
#define PORT  8080
#define BUFFER_SIZE 1024
int main(int argc, char **argv)
{
    //定义IPV4的TCP连接的套接字描述符
    int sock_cli = socket(AF_INET,SOCK_STREAM, 0);
    //定义sockaddr_in
    struct sockaddr_in servaddr;
    memset(&servaddr, 0sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr(argv[1]);
    servaddr.sin_port = htons(PORT);  
 
    //连接服务器,成功返回0,错误返回-1
    int ret = connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr));
 
    //客户端将控制台输入的信息发送给服务器端,服务器原样返回信息,阻塞
    while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
    {   
        ret=send(sock_cli, sendbuf, strlen(sendbuf),0); ///发送
        recv(sock_cli, recvbuf, sizeof(recvbuf),0); ///接收
        fputs(recvbuf, stdout);
    }
 
    close(sock_cli); // 关闭连接
    return 0;
}

Código de programación del zócalo del lado S

int main(int argc, char **argv)
{
    //定义IPV4的TCP连接的套接字描述符
    int server_sockfd = socket(AF_INET,SOCK_STREAM, 0);
    //定义sockaddr_in
    struct sockaddr_in server_sockaddr;
    server_sockaddr.sin_family = AF_INET;
    server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_sockaddr.sin_port = htons(PORT);
 
    //bind成功返回0,出错返回-1
    if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)
 
    //listen成功返回0,出错返回-1,允许同时监听的连接数为QUEUE_SIZE
    if(listen(server_sockfd,QUEUE_SIZE) == -1)
 
    for(;;)
    {
        struct sockaddr_in client_addr;
        socklen_t length = sizeof(client_addr);
        //进程阻塞在accept上,成功返回非负描述字,出错返回-1
        int conn = accept(server_sockfd, (struct sockaddr*)&client_addr,&length);
 
        //处理数据部分
      ...
    }
 
    close(server_sockfd);
    return 0;
}

¿Por qué necesita tres apretones de manos para establecer un enlace? ¿Es posible hacerlo dos veces, pero no cuatro veces?

Al hacer esta pregunta, ¿qué es el entrevistador? Preguntado aquí por alguna razón, algunos no lo son. Ciertamente no. El estándar RFC se escribe así.

No me atrevo a responder de esta manera. El estándar es establecer un vínculo con tres apretones de manos, pero no cuatro veces. Si responde de esta manera, la recibirá correctamente. Nuestra entrevista para los compañeros de clase básicamente terminó hoy, vaya a su casa y espere noticias ...

El tío Long habló sobre este problema, ¿por qué no puede ser dos veces?

Si no envía SYN + ACK por segunda vez, pero solo envía un mensaje de confirmación ACK, solo podrá establecer una comunicación unidireccional y no podrá responder. TCP es comunicación full-duplex y se debe garantizar la confiabilidad.

Si se envía el segundo SYN + ACK, no se requiere respuesta. Habrá tres situaciones

Si falla el primer o segundo apretón de manos, el terminal C enviará repetidamente el mensaje SYN, esperando que el igual envíe un mensaje de confirmación, y el terminal S guardará todos los recursos de la conexión tcp. Una gran cantidad de tales situaciones hará que los recursos S se agoten.

En segundo lugar, el segundo apretón de manos es exitoso. Si S no recibe el ACK, enviará repetidamente el mensaje SYN + ACK.

3. Después del segundo apretón de manos, las dos partes piensan que la conexión se establece con éxito y pueden iniciar la comunicación. Si la conexión no está realmente establecida en este momento, el extremo S comenzará a enviar mensajes, lo que causará congestión en la red.

¿Por qué no puede ser cuatro veces?

En principio, cuatro veces es posible, es decir, el segundo ACK y SYN se envían en dos. Es completamente factible en teoría, pero TCP se basa en la premisa de ahorrar recursos de red.

También hay una respuesta superpuesta que no desmonta el segundo apretón de manos. Después del apretón de manos tres, el lado C continúa enviando mensajes SYN, que es en vano. Después de la tercera finalización, el enlace se ha establecido, sin importar cuántas veces sea en vano.

¿Qué sucede si ambas partes establecen una conexión al mismo tiempo?

TCP establece un enlace al mismo tiempo
TCP establece un enlace al mismo tiempo

Este es el caso donde ambas partes establecen vínculos al mismo tiempo. La situación no es mala. De todos modos, se puede establecer con éxito. Esto es seguro. Pero presta atención a dos puntos

Primero, solo se establece un enlace TCP full-duplex en este momento, no dos.

En segundo lugar, no hay CS entre las dos partes, y ambos extremos asumen dos roles al mismo tiempo, el cliente y el servidor.

Cuatro ondas para desconectar

Primero, observe todo el proceso y la transición de estado de las cuatro manos agitadas. La transición de estado se verá más de cerca.

Cuatro ondas para desconectar
Cuatro ondas para desconectar

El modo C / S todavía se usa para explicar este proceso.

La primera vez: cuando la aplicación del terminal C finaliza la transmisión de datos, enviará un segmento con una marca FIN adicional al terminal S (FIN significa final en inglés), luego el terminal C ingresa al estado FIN_WAIT1, y el terminal C no puede enviar datos Al lado S.

La segunda vez: el extremo S responderá a un mensaje ACK después de recibir el mensaje FIN, y el extremo S entrará en el estado CLOSE_WAIT. Después de ingresar a este estado, el terminal S envía los datos restantes no enviados al terminal C. Después de recibir el ACK del terminal S, el terminal C ingresa al estado FIN_WAIT2.

Al mismo tiempo, continúe aceptando otros paquetes de datos transmitidos por el terminal S.

La tercera vez: después de que el terminal S procesa los datos que se enviarán, también enviará una solicitud de desconexión FIN, y el terminal S ingresa al estado LAST_ACK.

Cuarta vez: después de recibir la solicitud de desconexión del terminal S, el terminal C inicia un temporizador con una duración de 2MSL (Tiempo máximo de segmento para vivir) y envía el último mensaje ACK al mismo tiempo.

¿Por qué agitar cuatro veces?

TCP es un mecanismo de comunicación full-duplex, y cada dirección debe cerrarse individualmente.

El principio de cerrar la conexión de transmisión TCP es el siguiente:

Cuando un extremo completa su tarea de transmisión de datos, puede enviar un segmento de datos con el campo FIN establecido en 1 para terminar la transmisión de datos en esta dirección; cuando el otro extremo recibe este segmento de datos FIN, debe notificar a su capa de aplicación que el par ha finalizado Transferencia de datos en esa dirección.

¿Por qué no podemos usar el mecanismo de respuesta superpuesta en un apretón de manos de tres vías para reducir el apretón de manos de una vía?

Esto es muy confuso, pero no es difícil comprender algunos detalles de la transmisión TCP.

TCP es comunicación full-duplex . Después de que S recibe la solicitud de desconexión, solo significa que el terminal C no transmitirá datos al terminal S, pero no significa que el terminal S no transmita datos al terminal C.

Si se utiliza a cuestas, el terminal S no podrá transmitir los datos restantes al terminal C.

¿Por qué debo esperar 2 msl después del último ACK?

La red no es confiable y TCP es un protocolo confiable. Debe asegurarse de que se entregue el último mensaje antes de poder desconectar el enlace; de ​​lo contrario, volverá a recibir la información del mensaje FIN en el lado S.

El tiempo de espera de 2MSL es para garantizar que se puede reenviar cuando se pierde el último paquete.

¿Por qué es el tiempo de 2MSL?

2MSL es el tiempo máximo para un viaje de ida y vuelta del mensaje. Si es menor que este tiempo, el ACK se perderá, pero hemos reenviado el ACK antes de recibir el FIN de la otra parte.

¿Qué sucede si se establece la conexión pero el cliente falla repentinamente?

No es difícil para TCP hacer su propia garantía. TCP tiene un temporizador por defecto. El temporizador se configurará después de cada solicitud del cliente. Generalmente se establece en dos horas, y no se han recibido datos después de más de dos horas.

El servidor enviará un mensaje de sonda, cada 75 segundos a partir de entonces. Si aún no hay respuestas después de enviar 10 mensajes de prueba seguidos, el servidor considera que el cliente ha fallado y luego cierra la conexión.

Resumen

El conocimiento de tres apretones de manos y cuatro titubeos básicamente ha llegado a su fin, y he llegado a esto. Si hay algo que no entiendo, puede agregarme para discutir en WeChat.

Habrá una herramienta de línea de comandos de Linux comúnmente utilizada en la programación de red más adelante, como ping, tcpdump, netstat, nc, etc., y un artículo resumido sobre la red informática. Esta parte de la red informática está básicamente terminada, si no la comprende, puede consultar el artículo anterior en la cuenta oficial.

109 artículos originales publicados · Me gusta 442 · Visitas 110,000+

Supongo que te gusta

Origin blog.csdn.net/qq_38646470/article/details/105522263
Recomendado
Clasificación