si un cliente tcp envía un paquete, con número de secuencia de 10000 a 20000, a un servidor tcp. El TCP responderá con un ACK con seq_ack 20001.
si intercepto el paquete TCP del cliente y lo divido en 2 segmentos tcp, uno con seq de 10000 a 15000 y el otro con seq de 15001 a 20000. Y luego estos 2 segmentos TCP se envían al servidor TCP. Suponga que el segundo segmento se pierde en el camino. El servidor TCP responderá un ACK con seq_ack 15001.
Ahora, dado que el cliente TCP envía un paquete integral con seq 10000 a 20000, pero obtiene un ACK con 15001, desde el punto de vista del cliente, esto es extraño. ¿Cómo va a reaccionar? En teoría, el cliente debe retransmitir los bytes de la secuencia 15001 a 20000, es decir, el cliente transmitirá nuevos paquetes de la secuencia 15001. Pero, ¿qué tal la práctica, en la implementación de la pila TCP, es la misma que en la teoría?
Creo que en el búfer de envío TCP, cuando se envía un segmento tcp, el segmento aún permanece allí hasta el ACK. Cuando llega el ACK, estos bytes para el segmento se borran del búfer. Hay un puntero en el búfer de envío, cuando llega un ACK, el puntero apunta a la ubicación a la que corresponde el ack_seq. Los bytes que están debajo de ack_seq se borran. De esta manera, ¿no es necesario retransmitir todo el segmento?
fuente
Los tamaños de segmento pueden (y lo hacen) cambiar durante la vida útil de una conexión. Afortunadamente, TCP no tiene necesidad de registrar el tamaño del segmento con el que se enviaron previamente los paquetes individuales. Por lo tanto, hará lo siguiente:
Ambas operaciones se realizan independientemente del tamaño del segmento en el que se enviaron originalmente estos bytes. Por lo tanto, la teoría debería coincidir con la mayoría de las implementaciones.
Permítanme dar algunos antecedentes para explicar:
¿TCP utiliza bytes o segmentos? Para la aplicación, TCP expone una interfaz de flujo de bytes. Además, todos los campos de encabezado y variables internas están en bytes. Sin embargo, para transmitir información, TCP los divide en segmentos, ya que enviar bytes uno por uno sería un desperdicio :-). El uso de contadores de bytes en todas partes tiene la ventaja de que el tamaño del segmento no necesita permanecer constante durante la vida útil de la conexión:
Por cierto: SACK no es la respuesta aquí, ya que el receptor (típicamente) solo usará SACK si reconoce un agujero en el flujo de bytes (es decir, si un paquete se perdió pero llegó un paquete siguiente).
fuente