Читаем Компьютерные сети. 6-е изд. полностью

Хотя TCP-соединения полнодуплексные, чтобы понять, как происходит их разъединение, лучше считать их парами симплексных соединений. Каждое симплексное соединение разрывается независимо от своего напарника. Чтобы его разорвать, любая из сторон может отправить TCP-сегмент с установленным битом FIN; это означает, что у него больше нет данных для передачи. После подтверждения TCP-сегмента это направление закрывается. Тем не менее данные могут продолжать передаваться неопределенно долго в противоположную сторону. Соединение разрывается, когда закрываются оба направления. Обычно для разрыва требуются четыре TCP-сегмента: по одному с битом FIN и по одному с битом ACK в каждом направлении. Первый бит ACK и второй бит FIN могут также содержаться в одном TCP-сегменте, что уменьшит количество сегментов до трех.

Как при телефонном разговоре, когда оба участника могут одновременно попрощаться и повесить трубку, оба конца TCP-соединения могут отправить FIN-сегменты в одно и то же время. Они оба получают обычные подтверждения, и соединение закрывается. По сути, между одновременным и последовательным разъединением нет никакой разницы.

Чтобы избежать проблемы «двух армий» (см. раздел 6.2.3), используются таймеры. Если ответ на отправленный FIN-сегмент не приходит в течение двух максимальных интервалов времени жизни пакета, отправитель FIN-сегмента разрывает соединение. Другая сторона в конце концов заметит, что ей никто не отвечает, и также отсоединится. Эта схема несовершенна, однако, учитывая недостижимость идеала, приходится пользоваться тем, что есть. На практике проблемы возникают довольно редко.

6.5.7. Модель управления TCP-соединением

Этапы, необходимые для установления и разрыва соединения, могут быть представлены в виде модели конечного автомата, 11 состояний которого перечислены на илл. 6.38. В каждом из этих состояний разрешены определенные события, в ответ на которые могут осуществляться действия. При возникновении каких-либо других событий сообщается об ошибке.

Каждое соединение начинается в состоянии CLOSED (закрыто). Оно может покинуть это состояние, предпринимая либо активную (CONNECT), либо пассивную (LISTEN) попытку открыть соединение. Если другая сторона осуществляет противоположное действие, соединение устанавливается и переходит в состояние ESTABLISHED. Инициатором разрыва соединения может выступить любая сторона. По завершении этого процесса соединение возвращается в состояние CLOSED.

Состояние

Описание

CLOSED

Закрыто. Соединение не является активным и не находится в процессе установления

LISTEN

Ожидание. Сервер ожидает входящего запроса

SYN RCVD

Прибыл запрос соединения. Ожидание подтверждения

SYN SENT

Запрос соединения отправлен. Приложение начало открывать соединение

ESTABLISHED

Установлено. Нормальное состояние передачи данных

FIN WAIT 1

Приложение сообщило, что ему больше нечего передавать

FIN WAIT 2

Другая сторона согласна разорвать соединение

TIME WAIT

Ожидание, пока из сети не исчезнут все пакеты

CLOSING

Обе стороны попытались одновременно закрыть соединение

CLOSE WAIT

Другая сторона инициировала разъединение

LAST ACK

Ожидание, пока из сети не исчезнут все пакеты

Илл. 6.38. Состояния конечного автомата, управляющего TCP-соединением

Конечный автомат показан на илл. 6.39. Типичный случай клиента, активно соединяющегося с пассивным сервером, показан жирными линиями — сплошными для клиента и пунктирными для сервера. Тонкие линии обозначают необычные последовательности событий. Каждая линия на илл. 6.39 маркирована парой событие/действие. Событие может представлять собой либо обращение пользователя к системной процедуре (CONNECT, LISTEN, SEND или CLOSE), либо прибытие сегмента (SYN, FIN, ACK или RST), либо, в одном случае, окончание периода ожидания, равного двойному времени жизни пакетов. Действие может состоять в отправке управляющего сегмента (SYN, FIN или RST). Впрочем, может не предприниматься никакого действия, что обозначается прочерком. В скобках приводятся комментарии.

Диаграмму проще понять, если сначала проследовать по пути клиента (сплошная жирная линия), а затем — по пути сервера (жирный пунктир). Когда приложение на устройстве клиента вызывает операцию CONNECT, локальная TCP-подсистема создает запись соединения, помечает его состояние как SYN SENT и отправляет SYN-сегмент. Обратите внимание, что несколько приложений одновременно могут открыть множество соединений, и состояние каждого из них хранится в записи соединения. Когда прибывает сегмент SYN + ACK, TCP-подсистема отправляет последний ACK-сегмент «тройного рукопожатия» и переключается в состояние ESTABLISHED. В этом состоянии можно пересылать и получать данные.

Перейти на страницу:

Похожие книги