El protocolo de enlace TCP de 3 vías funciona así:
Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server
¿Por qué no solo esto?
Client ------SYN-----> Server
Client <-----ACK------ Server
El protocolo de enlace TCP de 3 vías funciona así:
Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server
¿Por qué no solo esto?
Client ------SYN-----> Server
Client <-----ACK------ Server
Respuestas:
Divide el apretón de manos en lo que realmente está haciendo.
En TCP, las dos partes realizan un seguimiento de lo que han enviado utilizando un número de secuencia. Efectivamente, termina siendo un recuento de bytes en ejecución de todo lo que se envió. La parte receptora puede usar el número de secuencia del hablante opuesto para reconocer lo que ha recibido.
Pero el número de secuencia no comienza en 0. Comienza en el ISN (Número de secuencia inicial), que es un valor elegido al azar. Y dado que TCP es una comunicación bidireccional, ambas partes pueden "hablar" y, por lo tanto, ambas deben generar aleatoriamente un ISN como su Número de secuencia inicial. Lo que a su vez significa que ambas partes deben notificar a la otra parte de su ISN inicial.
Entonces terminas con esta secuencia de eventos para comenzar una conversación TCP entre Alice y Bob:
Alice ---> Bob SYNchronize with my Initial Sequence Number of X
Alice <--- Bob I received your syn, I ACKnowledge that I am ready for [X+1]
Alice <--- Bob SYNchronize with my Initial Sequence Number of Y
Alice ---> Bob I received your syn, I ACKnowledge that I am ready for [Y+1]
Observe que están ocurriendo cuatro eventos:
Sin embargo, en realidad, los dos eventos intermedios (# 2 y # 3) ocurren en el mismo paquete. Lo que hace que un paquete sea un SYN
o ACK
simplemente un indicador binario activado o desactivado dentro de cada encabezado TCP , por lo que no hay nada que impida que ambos indicadores se habiliten en el mismo paquete. Entonces el apretón de manos de tres vías termina siendo:
Bob <--- Alice SYN
Bob ---> Alice SYN ACK
Bob <--- Alice ACK
Observe las dos instancias de "SYN" y "ACK", una de cada una, en ambas direcciones.
Entonces, para volver a su pregunta, ¿por qué no usar un apretón de manos de dos vías? La respuesta corta es porque un apretón de manos de dos vías solo permitiría que una parte establezca un ISN y la otra parte lo reconozca. Lo que significa que solo una parte puede enviar datos.
Pero TCP es un protocolo de comunicación bidireccional, lo que significa que cualquiera de los extremos debería poder enviar datos de manera confiable. Ambas partes deben establecer un ISN, y ambas partes deben reconocer el ISN de la otra.
En efecto, lo que tiene es exactamente su descripción del apretón de manos de dos vías, pero en cada dirección . Por lo tanto, se producen cuatro eventos. Y nuevamente, las dos banderas del medio ocurren en el mismo paquete. Como tales tres paquetes están involucrados en un proceso de inicio de conexión TCP completo.
El enlace de tres vías es necesario porque ambas partes deben syn chronize sus números de secuencia de segmentos utilizados durante su transmisión. Para ello, cada uno de ellos envía (a su vez) un segmento SYN con un número de secuencia se establece en un valor aleatorio n , que luego se ack nowledged por la otra parte a través de un segmento ACK con un número de secuencia se establece en n + 1 .
Eddie
comentario de su respuesta.
Para que la conexión funcione, cada lado debe verificar que puede enviar paquetes al otro lado. La única manera de asegurarse de que tiene un paquete al otro lado es obtener un paquete de ellos que, por definición, no se hubiera enviado a menos que el paquete que envió se haya enviado . TCP utiliza esencialmente dos tipos de mensajes para esto: SYN (para solicitar la prueba de que este paquete pasó) y ACK (que solo se envía después de que un SYN pasa, para probar que SYN pasó). En realidad hay un tercer tipo de mensaje, pero llegaremos a eso en un momento.
Antes de que comience la conexión, ninguno de los lados sabe realmente nada del otro. El cliente envía un paquete SYN al servidor, para solicitar pruebas de que sus mensajes pueden pasar . Eso no le dice nada a ninguna persona, pero es el primer paso del apretón de manos.
Si el SYN pasa, entonces el servidor sabe que el cliente puede enviarle paquetes, porque, bueno, simplemente sucedió. Pero eso no prueba que el servidor pueda enviar paquetes de vuelta: los clientes pueden enviar SYN por muchas razones . Por lo tanto, el servidor debe enviar dos mensajes de regreso al cliente: un ACK (para demostrar que el SYN logró pasar) y un SYN (para solicitar un ACK propio). TCP combina estos dos mensajes en uno, un mensaje SYN-ACK, si lo desea, para reducir el tráfico de red. Este es el segundo paso del apretón de manos.
Debido a que un SYN-ACK es un ACK, el cliente ahora sabe con certeza que puede enviar paquetes al servidor. Y debido a que un SYN-ACK es un SYN, también sabe que el servidor quiere pruebas de que este mensaje llegó. Por lo tanto, devuelve un ACK: solo un ACK simple esta vez, porque ya no necesita pruebas de que sus paquetes puedan pasar. Este es el paso final del apretón de manos: el cliente ahora sabe que los paquetes pueden ir en ambos sentidos, y que el servidor está a punto de resolver esto (porque sabe que el ACK pasará).
Una vez que ese ACK pasa, ahora el servidor sabe que puede enviar paquetes al cliente . También sabe que el cliente lo sabe, por lo que puede comenzar a enviar datos de inmediato. El apretón de manos está completo. Tenemos un buen canal
Bueno, estrictamente hablando, no podemos estar seguros de tener un buen canal . El hecho de que esta secuencia de paquetes haya pasado no garantiza estrictamente que otros lo harán. No podemos probar eso sin enviar un número infinito de SYN y ACK, y luego nada más se haría, por lo que esa no es realmente una opción práctica. Pero en la práctica, tres pasos resultan ser lo suficientemente buenos para la mayoría de los propósitos .
En realidad, un apretón de manos de 3 vías no es el único medio para establecer una conexión TCP. También se permite el intercambio simultáneo de SYN: http://www.tcpipguide.com/free/t_TCPConnectionEstablishmentProcessTheThreeWayHandsh-4.htm
Eso podría verse como una especie de doble apretón de manos de dos vías.
La conexión TCP es bidireccional. Lo que esto significa es que en realidad es un par de conexiones unidireccionales. El iniciador envía SYN, el respondedor envía ACK: comienza una conexión simplex. "Entonces" el respondedor envía SYN, el iniciador envía ACK: comienza otra conexión simplex. Dos conexiones simples forman una sesión TCP dúplex, ¿de acuerdo? Entonces, lógicamente, hay cuatro pasos involucrados; pero debido a que los indicadores SYN y ACK son diferentes "campos" del encabezado TCP, se pueden configurar simultáneamente: el segundo y el tercer paso (de los cuatro) se combinan, por lo que técnicamente hay tres intercambios de paquetes. Cada conexión simple (media) usa intercambio bidireccional, como usted propuso.
Si el servidor y el cliente desean crear una conexión, deben confirmar cuatro cosas:
El cliente debe confirmar que puede recibir el paquete del servidor
El cliente necesita confirmar algo: el servidor puede recibir paquetes del cliente
Después Client ------SYN-----> Server
, se confirma la regla 1.
Después Client <---ACK/SYN---- Server
, se confirman las reglas 2 y 3.
Entonces, se necesita un tercer paquete para confirmar la regla 4.
No es necesario en absoluto. Es obvio que un mensaje corto solo debe requerir un paquete para el servidor que incluye el mensaje de inicio +, y un paquete de regreso que lo reconozca.
Las respuestas anteriores solo describen el sistema sin discutir la necesidad de números de secuencia aleatorios, etc. en primer lugar. La pregunta original era sobre el diseño del propio TCP: obviamente, si usa el protocolo TCP, entonces necesita tres mensajes porque ese es el protocolo. Pero, ¿por qué se diseñó TCP de esa manera en primer lugar?
Creo que la idea original era que no había distinción entre clientes y servidores. Ambos conocían los puertos del otro de manera bidireccional, y cualquiera podía comenzar la conversación. Y eso requería Syns, etc.
Pero esto no es, por supuesto, cómo se usa hoy. El servidor escucha en un puerto conocido y lo hace y "acepta", el número de puerto del cliente es efímero. Ni siquiera creo que sea posible que un servidor que espera un "aceptar" envíe una solicitud a otro en el mismo número de puerto del cliente en los sistemas operativos normales.
(Tenga en cuenta que esto se trata del inicio bidireccional de la conexión, lo que nunca se hace hoy en día. Eso es muy diferente de enviar mensajes bidireccionales a través de una conexión una vez establecida).
Para evitar la ineficiencia de TCP, utilizamos protocolos como HTTP 1.1 que pueden reutilizar la misma conexión para múltiples solicitudes, y así evitar el protocolo de enlace TCP que no era necesario en primer lugar.
Pero Http 1.1 es relativamente nuevo. Y SSL / TLS necesitaba una forma de reutilizar la sesión desde el principio debido al costo de los algoritmos PKI. De modo que ese protocolo incluye su propio mecanismo de reutilización de sesión que se ejecuta sobre Http 1.1 que se ejecuta sobre TCP.
Tal es el camino con el software. Fudges en kludges que, cuando se combinan, producen un resultado aceptable.
Después de leer la respuesta de Eddie (aceptado como correcto), todavía hay dudas de por qué el primer host no puede asignar ambos ISN con números aleatorios y el segundo simplemente lo acepta. La verdadera razón del uso del apretón de manos de 3 vías es evitar las medias conexiones . Escenario de media conexión en protocolo de enlace bidireccional:
1) Cliente --- SYN -> Servidor
2) El cliente cambia de opinión y ya no quiere conectarse
3) Cliente <-X-ACK-- Servidor // Se perdió ACK
El servidor no ve SYN reenviado, por lo que cree que el cliente recibió su ACK y se estableció la conexión. Como resultado, el servidor tiene una conexión que nunca se cerrará