Тайм-ауты и повторные передачи TCP

         

Как получатель избавляется от синдрома глупого окна



Рисунок 22.3 Как получатель избавляется от синдрома глупого окна.

В первой колонке на рисунке 22.3 приводится относительный момент времени соответствующий каждому действию. Величины времени с тремя цифрами справа от десятичной точки взяты из вывода команды tcpdump (рисунок 22.2). Величины времени со значением 99 справа от десятичной точки - это предполагаемая продолжительность функционирования принимающего хоста. (Наличие этих относительных времен на принимающем конце и содержащих 99 в позиции сотых долей секунд указывает на их взаимосвязь с сегментами 20 и 22 на рисунке 22.2, только два события на приемнике, которые мы видим в выводе команды tcpdump, произошли на принимающем хосте по тайм-ауту. Все другие пакеты, отправленные bsdi, отправлены по приему сегмента от отправителя. Также необходимо принять во внимание, что это могло бы поместить исходную 4-секундную паузу непосредственно перед моментом времени 0, когда отправитель передает первый сегмент данных. Это примерно тогда, когда получатель берет управление после приема подтверждения на свой SYN при установлении соединения.)

Размер буфера приемника увеличивается, когда он получает данные от получателя, и уменьшается, когда приложение считывает данные из буфера. Нам необходимо проследить за объявлениями окна, которые отправляются получателем отправителю, и за тем, что содержат эти объявления окна. Таким образом, мы можем увидеть, как получатель избегает синдрома глупого окна.

Первые четыре сегмента данных и соответствующие ACK (сегменты 1-5) показывают, что отправитель заполнил буфер приемника. В этой точке отправитель останавливается, однако у него все еще остались данные, которые необходимо отправить. Он устанавливает свой устойчивый таймер в минимальное значение равное 5 секундам.

Когда таймер истек, посылается 1 байт данных (сегмент 6). Принимающее приложение считало 256 байт из приемного буфера (в момент времени 3,99), таким образом, байт принимается и подтверждается (сегмент 7). Однако, объявленное окно все еще равно 0, так как у приемника нет места равного одному сегменту полного размера или половине своего буфера. Именно таким образом, получатель избегает появления синдрома глупого окна.

Устойчивый таймер отправителя сбрасывается и устанавливается снова через 5 секунд (момент времени 10,151). Снова отправляется и подтверждается один байт (сегменты 8 и 9). И снова, размер свободного места в буфере приемника (1022 байта) заставляет его объявить окно равное 0.

Когда устойчивый таймер отправителя истекает в следующий раз (в момент времени 15,151), отправляется и подтверждается еще один байт (сегменты 10 и 11). В это время получатель имеет в буфере 1533 байта свободного пространства, поэтому объявляется окно ненулевого размера. Отправитель немедленно пользуется этим и отправляет 1024 байта (сегмент 12). Подтверждение на эти 1024 байта (сегмент 13) объявляет окно равное 509 байт. Это противоречит тому, что мы видели раньше с объявлениями маленьких окон.

Здесь произошло следующее: сегмент 11 объявил окно размером 1533 байта, однако отправитель отправил только 1024 байта. Если подтверждение в сегменте 13 объявит окно равное 0, это будет противоречить принципу TCP, который заключается в том, что окно не может изменяться путем перемещения его правого края влево (глава 20, раздел "Изменение размера окна"). Именно поэтому должно быть объявлено маленькое окно размером в 509 байт.

Затем необходимо обратить внимание на то, что отправитель отправляет это маленькое окно не сразу. Это уже меры, которые принимает отправитель, чтобы избавиться от синдрома глупого окна. Отправитель ожидает истечения еще одного устойчивого таймера (момент времени 20,151) и только тогда посылает 509 байт. Даже если все равно отправляется маленький сегмент размером 509 байт данных, отправитель ожидает 5 секунд, чтобы посмотреть, не придет ли ACK и не объявит ли большее окно. После прихода 509 байт данных в буфере приемника остается всего лишь 768 байт свободного места, поэтому подтверждение (сегмент 15) объявляет окно равное 0.

Устойчивый таймер снова включается в момент времени 25,151, а отправитель передает 1 байт. В буфере получателя этот момент 1279 байт свободного пространства, окно такого размера объявляется в сегменте 17.

Отправителю необходимо отправить только 511 дополнительных байт, которые он немедленно отправляет после получения объявления окна размером 1279 байт (сегмент 18). Этот сегмент также содержит флаг FIN. Получатель подтверждает данные и FIN, объявляя окно размером 767. (См. упражнение 2 в конце главы.)

Так как отправляющее приложение выдало сигнал закрытия, после того как сделало шесть записей размером 1024 байта, соединение со стороны отправителя переходит из состояния ESTABLISHED в состояние FIN_WAIT_1, затем в состояние FIN_WAIT_2 (рисунок 18.12).

Оно остается в этом состоянии до получения FIN с удаленного конца. Для этого состояния не существует таймера (обратитесь к нашему обсуждению в конце раздела "Диаграмма состояний передачи TCP" главы 18), поэтому FIN, который был отправлен в сегменте 18, подтверждается в сегменте 19. Именно поэтому мы не видим дальнейшей передачи от отправителя до тех пор, пока он не получил FIN (сегмент 21).

Получающее приложение продолжает читать 256 байт данных каждые 2 секунды из приемного буфера. Почему ACK отправлен в момент времени 39,99 (сегмент 20)? Размер свободного места в буфере получателя увеличился с момента последнего объявления окна размером 767 (сегмент 19) до 2816, когда приложение осуществило чтение в момент времени 39,99. Таким образом, в приемном буфере появилось 2049 байт свободного пространства. Обратитесь к первому правилу, с которого мы начали этот раздел, в соответствии с которым получатель отправляет обновление окна, потому что количество свободного места увеличилось на величину, равную половине размера приемного буфера. Это означает, что получающий TCP каждый раз проверяет, нужно ли послать обновления окна, когда приложение считывает данные из приемного буфера TCP.

Последнее чтение, осуществленное приложением, происходит в момент времени 51,99, и приложение получает уведомление о конце файла, так как буфер пуст. Два последних сегмента (21 и 22) завершают разрыв соединения.



Содержание раздела