Соединение данных для двух последовательных команд LIST
Рисунок 27.8 Соединение данных для двух последовательных команд LIST.
Последовательность событий в данном случае следующая.
- Управляющее соединение устанавливается от порта клиента 1176 на порт сервера 21. (Здесь это не показано.)
- Когда клиент осуществляет пассивное открытие для соединения данных на порт 1176, он должен указать опцию SO_REUSEADDR, так как этот порт уже используется управляющим соединением клиента.
- Сервер осуществляет активное открытие соединения данных (сегмент 1) с порта 20 на порт 1176. Клиент принимает это (сегмент 2), даже если порт 1176 уже используется клиентом, потому что две пары сокетов
<svr4, 1176, bsdi, 21>
<svr4, 1176, bsdi, 20>
различны (номер порта на bsdi отличается). TCP демультиплексирует входящие сегменты, просматривая IP адрес источника, номер порта источника, IP адрес назначения и номер порта назначения, поэтому пока один из четырех элементов отличается, все в порядке.
Сервер осуществляет активное закрытие соединения данных (сегмент 5), при этом пара сокетов на сервере
<svr4, 1176, bsdi, 20>
помещается в состояние ожидания 2MSL.
Клиент отправляет еще одну команду LIST по управляющему соединению. (Мы не показали этого.) Перед этим клиент осуществляет пассивное открытие порта 1176 на своем конце соединения данных. Клиент должен указать снова опцию SO_REUSEADDR, так как номер порта 1176 уже используется.
Сервер осуществляет активное открытие соединения данных с порта 20 на порт 1176. Перед тем как сделать это, сервер должен указать SO_REUSEADDR, так как локальный порт (20) связан с соединением, которое находится в состоянии ожидания 2MSL, однако, как мы показали в разделе "Диаграмма состояний передачи TCP" главы 18, соединение открыть не удасться. Дело в том, что пара сокет для требуемого соединения эквивалентна паре сокет из шага 4, которая все еще находится в состоянии ожидания 2MSL. Правила TCP запрещают серверу отправить SYN. Для сервера не существует способа игнорировать состояние 2MSL для пары сокетов, если ему понадобилось повторно использовать эту же пару сокетов.
В этом месте BSD серверы повторяют попытки установить соединение каждые 5 секунд, до 18 раз, что в целом составляет 90 секунд. Мы видим, что сегмент 9 успешно прошел примерно через одну минуту. (Мы говорили в главе 18, что SVR4 использует MSL равное 30 секундам, при этом получается, что ожидание 2MSL составляет 1 минуту.) Мы не увидим ни одного SYN в это время на временной диаграмме, потому что активное открытие не удалось, и TCP модуль сервера даже не пытается посылать SYN.
Причина, по которой требования к хостам Host Requirements RFC рекомендуют использовать команду PORT, заключается в том, что эта команда позволяет обойти состояние ожидания 2MSL между последовательными использованиями соединения данных. Так как порты последовательно меняются на одном конце, проблема, которую мы только что показали, исчезает сама собой.
Содержание раздела