если клиент tcp отправляет пакет с порядковым номером от 10000 до 20000 на сервер tcp. TCP отвечает ACK с seq_ack 20001.
если я перехватываю пакет TCP от клиента и делю пакет на 2 сегмента tcp, один с seq от 10000 до 15000, а другой с seq от 15001 до 20000. И затем эти 2 сегмента TCP отправляются на сервер TCP. Предположим, что второй сегмент потерян в пути. TCP-сервер ответит ACK с помощью seq_ack 15001.
Теперь, когда TCP-клиент отправляет целостный пакет с последовательностями от 10000 до 20000, но он получает ACK с 15001, с точки зрения клиента, это странно. Как это отреагирует? Теоретически, клиент должен повторно передать байты с seq 15001 до 20000, а именно, клиент будет передавать новые пакеты с seq 15001. Но как насчет практики, в реализации стека TCP, она такая же, как в теории?
Я думаю, что в буфере отправки TCP, когда сегмент TCP отправляется, сегмент все еще остается там до ACK. Когда приходит ACK, эти байты для сегмента очищаются из буфера. В буфере отправки есть указатель, когда приходит ACK, указатель указывает на местоположение, которому соответствует ack_seq. Байты, которые находятся ниже ack_seq, очищаются. Таким образом, весь сегмент не должен быть передан повторно?
источник
Размеры сегментов могут (и могут) изменяться в течение срока жизни соединения. К счастью, TCP не нужно записывать размер сегмента, с которым отдельные пакеты были отправлены ранее. Поэтому он будет делать следующее:
Обе операции выполняются независимо от размера сегмента, в который эти байты были изначально отправлены. Поэтому теория должна соответствовать большинству реализаций.
Позвольте мне дать некоторые пояснения, чтобы объяснить:
TCP использует байты или сегменты? Для приложения TCP предоставляет интерфейс потока байтов. Кроме того, все поля заголовка и внутренние переменные в байтах. Однако для передачи информации TCP разбивает их на сегменты, так как посылка байтов по одному была бы довольно бесполезной :-). Повсеместное использование счетчиков байтов имеет то преимущество, что размер сегмента не должен оставаться постоянным в течение всего времени жизни соединения:
КСТАТИ: SACK не является ответом здесь, так как получатель (как правило) будет использовать SACK, только если он распознает дыру в байтовом потоке (то есть, если пакет потерян, но пришел следующий пакет).
источник