1

Когда соединение TCP закрыто на одном конце соединения - другой конец получает FIN и отвечает ACK . Этот конец соединения переходит в состояние CLOSE_WAIT . После вызова close() на этом конце TCP отправляет пакет FIN и переходит в состояние LAST_ACK . Однако он никогда не переходит в TIME_WAIT .

Диаграмма переходов между состояниями TCP

Теперь предположим, что узел A вызывает сокет close() и отправляет пакет FIN узлу B. Узел A переходит в состояние FIN_WAIT_1 . Хост B получает пакет FIN , отправляет ACK и затем переходит в состояние CLOSE_WAIT . Однако ACK сбрасывается где-то в восходящем маршрутизаторе.

Между тем, узел B вызывает метод close() (напомним, что узел B находится в состоянии CLOSE_WAIT ) и отправляет пакет FIN узлу A. Теперь узел B переходит в состояние LAST_ACK . Хост A получает пакет FIN и отвечает ACK . Затем он переходит в состояние CLOSING .

На другом конце хост B все еще находится в состоянии LAST_ACK . Затем он получает ACK от хоста A и переходит в состояние CLOSED . Вспомните, что ACK от хоста B к хосту A был отброшен и что хост A не повторно отправил свой пакет FIN . Узел A повторно отправляет свой пакет FIN по истечении времени ожидания, однако узел B закрыл соединение.

Хост А теперь застрял в состоянии CLOSING ? Разрыв соединения может продолжаться? Что происходит дальше?

1 ответ1

0

Мой TCP немного ржавый, но я считаю, что он работает так:

Когда хост B вызывает close() и отправляет свой FIN , порядковый номер на этом FIN сообщит хосту A, что он пропустил пакет от хоста B. Таким образом, хост A не будет подтверждать FIN хоста B, он сохранит подтверждение последний сегмент TCP, который он успешно получил от хоста B. Это побудит хост B повторно передать отсутствующий ACK .

Таким образом, Хост А не достигнет состояния CLOSING , потому что он не будет считать, что FIN действительно получен, пока не получит отсутствующий ACK , предшествующий ему.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .