networking - transmision - ¿TCP envía un SYN/ACK en cada paquete o solo en la primera conexión?
tcp significado (3)
Es como:
+-------------------------------------------------------+
| client network server |
+-----------------+ +--------------------|
| (connect) | ---- SYN ----> | |
| | <-- SYN,ACK -- | (accepted) |
| (connected) | ---- ACK ----> | |
/_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_/
when client sends...
/_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_/
| | | |
| (send) | ---- data ---> | |
| | <---- ACK ---- | (data received) |
/_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_/
when server sends...
/_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_/
| | | |
| | <--- data ---- | (send) |
| (data received) | ---- ACK ----> | |
/_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_/
...and so on, til the connection is shut down or reset
SYN inicia una conexión; por lo general, solo lo verás cuando se establezca la conexión. Pero todos los datos que se envían a través de TCP requieren un ACK. Cada byte enviado debe ser contabilizado, o será retransmitido (o el restablecimiento de conexión (cerrado), en casos severos).
Sin embargo, las conexiones reales no son exactamente iguales al diagrama anterior por dos motivos:
- Los ACK pueden acumularse, por lo que un ACK puede confirmar todo lo recibido hasta ese momento. Eso significa que puede acusar recibo de dos o más envíos con un ACK.
- Un ACK es simplemente una bandera y un campo en un encabezado TCP. Enviar uno requiere al menos un valor de ancho de banda de un encabezado, más lo que sea que las capas más bajas se ajusten. Pero los segmentos de datos ya incluyen todo eso ... así que si está enviando datos, puede enviar un ACK al mismo tiempo de forma gratuita.
La mayoría de las pilas TCP / IP intentan reducir el número de ACK desnudos sin arriesgar excesivamente la retransmisión o restablecer la conexión. Entonces, una conversación como esta es bastante posible:
/_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_/
| | | |
| | <--- data ---- | (send) |
| (data received) | | |
| (send) | -- data,ACK -> | |
| | | (data received) |
| | <- data,ACK -- | (send) |
| (data received) | | |
| (wait a bit) | <--- data ---- | (send) |
| (data received) | | |
| (send) | -- data,ACK -> | |
| | | (data received) |
| (send) | ---- data ---> | (wait a bit) |
| | | (data received) |
| | <- data,ACK -- | (send) |
| (data received) | | |
| (wait a bit) | (dead air) | |
| | ---- ACK ----> | |
/_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_//_/
En cuanto a UDP, no existe un concepto integrado de SYN y ACK: UDP es, por naturaleza, "poco confiable" y no está orientado a la conexión, por lo que los conceptos no se aplican tanto. Su reconocimiento generalmente será la respuesta del servidor. Pero algunos protocolos de capa de aplicación construidos sobre UDP tendrán alguna manera específica de protocolo de reconocer los datos enviados y recibidos.
Tengo un servidor TCP que escucha a un cliente entrante y luego lo envía un paquete de datos por segundo. Me preguntaba si el paquete SYN / ACK solo se envía en la conexión inicial, por lo que se ve así:
<client connect>
SYN
ACK
DATA
DATA
DATA
<client disconnect>
¿O se envía con cada paquete, así?
<client connect>
SYN
ACK
DATA
SYN
ACK
DATA
SYN
ACK
DATA
<client disconnect>
Además, si es el primer caso, ¿hay algún beneficio de UDP sobre TCP si solo mantienes la conexión abierta durante un largo período de tiempo?
Imagínese esto: el estándar TCP original RFC 793 permitió que los datos se enviaran con el primer paquete SYN. Sin embargo, ese no es el caso hoy. Lo que obtienes es un paquete SYN separado durante el inicio del Apretón de Manos de Tres Vías del solicitante de la conexión. Supongamos que A solicita conectarse con B, por lo que A envía un paquete con un bit SYN establecido. B responde con un ACK para acusar recibo y envía A los paquetes ACK + SYN. Los datos pueden luego transmitirse de ahora en adelante.
Dordal tiene una muy buena explicación sobre este asunto. Haga clic en este enlace aquí.
SYN solo está al principio.
ACK está en segmentos subsiguientes en cualquier dirección. [edit] El ACK también definirá un tamaño de ventana. Si el tamaño de la ventana es 100, por ejemplo, el remitente puede enviar 100 segmentos antes de esperar recibir un ACK. Por ejemplo, si el emisor envía 100 segmentos pero se pierde el número 50, el receptor obtendrá 1-49 y 51 -100. El receptor ACK recibirá 50 (el siguiente segmento espera) y establecerá el tamaño de la ventana en 1. El remitente reenviará 1 segmento con el número de secuencia 50. El receptor ACK recibirá 101 y restablecerá el tamaño de la ventana a un número mayor [editar]
Ambos son en realidad campos en el encabezado TCP y se pueden enviar con datos, aunque el SYN y el primer ACK normalmente no tienen datos.
Entonces ninguno de los escenarios que describes es bastante correcto. El primero está realmente más cerca de la realidad, pero todos los paquetes de datos después del SYN tienen que incluir un ACK, y también un campo de número de acuse de recibo que identifica el número del próximo paquete esperado.
El final de una sesión también implica apretones de manos con paquetes marcados con FIN y ACK relacionados con ellos.
Los números de secuencia intercambiados se usan para identificar paquetes perdidos y habilitar un mecanismo de reintento, y también para volver a ensamblar todo el flujo de paquetes en el orden correcto.
Además, si es el primer caso, ¿hay algún beneficio de UDP sobre TCP si solo mantienes la conexión abierta durante un largo período de tiempo?
Con UDP no puede simplemente mantener la conexión abierta durante un largo período de tiempo. No hay conexión.
Esta secuencia de banderas SYN / ACK / FIN es lo que hace una conexión.
Con UDP, no hay SYN o ACK, por lo que la comunicación es unidireccional, la entrega no está garantizada y el orden no se preserva. Pero tiene menos sobrecarga, por lo que es útil cuando la velocidad es más importante que la confiabilidad, como por ejemplo en los medios de transmisión.
Esto es un poco simplificado aún, pero es lo mejor que puedo hacer en este momento.
Hay mucho más sobre esto en la entrada de wikipedia en TCP y, por supuesto, en las RFC.