Почему LAST_ACK не входит в CLOSE_WAIT?

Почему LAST_ACK не входит в CLOSE_WAIT?

Когда 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

Мой TCP немного заржавел, но я думаю, что он работает следующим образом:

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

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

Связанный контент