Поделиться Поделиться

Фаза установления соединения

В фазе установления соединения, предшествующей фазе передачи данных, выполняются следующие действия.

1. Хост А отправляет хосту Б запрос соединения, представляющий собой ТСР-сегмент с нулевым полем данных и с установленным флагом SYN; одновременно инициализируется начальное значение нумерующей последовательности (Seq_no = m).

2. Хост Б , если он готов принять запрашиваемое соединение, отвечает на этот запрос отправкой сегмента с нулевым полем данных и установленным флагом ACK. Поле «Порядковый номер подтверждения» содержитзначение на единицу большее значения m (Ack_no = m+1); одновременно, хост Б запрашивает соединение с хостом Aв противоположном направлении (SYN=1) и также инициализирует значение начального значения своей нумерующей последовательности (Seq_no = k). Если хост не готов принять соединение, или он получает команду ABORT от прикладного протокола, то этим хостом отправляется TCP-сегмент с установленным флагом RST.

3. Хост А отвечает на запрос соединения от хоста Ботправкой сегмента, в котором «Порядковый номер сегмента» устанавлен в значение m+1 (Seq_no = m+1), флаг ACK=1 и подтверждением ожидания следующего байта данных с порядковым номером k+1 (Ack_no = k+1).

Такая трехэтапная процедура установления соединения гарантирует согласование начальных значений нумерующих последовательностей взаимодействующих TCP-модулей, что принципиально важно для последующего функционирования соединения. Случайный характер выбора начальных значений Seq_no является достаточно надежной мерой, предупреждающей установление в двух последовательных соединениях одинаковых начальных номеров. Графическая иллюстрация этапов установления соединения представлена на рис. 6.19.

Протокол ТСР поддерживает два типа соединения – активное и пассивное. Так, в приложениях, построенных по клиент-серверной архитектуре, сервер выполняет пассивное соединение – его модуль ТСР формирует соответствующий сокет и переходит в режим «прослушивания» (режим готовности принять запрос соединения). Когда клиент желает установить связь с сервером, он выполняет процедуру активного соединения. В нее входит создание сокета на клиентской стороне и выполнение описанной выше трехэтапной процедуры TCP-соединения.

 
 Фаза установления соединения - Инвестирование - 1


Заметим, что в фазе установления соединения SYN-сегмент содержит определенный набор опциональных параметров. Одним из наиболее важных является параметр MSS. Поскольку ТСР работает на конечных хостах, то этот параметр не может нести информацию о максимально приемлемой величине сегмента на всем пути от источника до получателя. Величина MSS определяется значением MTU, которое является функцией канальной технологии. Однако, хост располагает достоверными сведениями только о значении MTU начального участка сетевого маршрута, к которому он непосредственно подключен. Ясно, что необходим какой-то механизм адаптации значения MSS к характеристикам сетевого пути. В 1988 году в RFC 1191 была предложена процедура Path MTU Discoverу (PMTUD). Суть процедуры состоит в том, что в IP-пакете, переносящем сегмент SYN, бит DF ("Dont Fragmen") устанавливается в 1, а в опциях заголовка этого ТСР-сегмента передается некоторое значение MSS. Тем самым хост, с которым устанавливается соединение, получает указание все сегменты по этому соединению отправлять в IP-пакетах с установленным битом DF и величиной, не превосходящей указанного значения MSS. В фазе передачи данных это заставит маршрутизатор, который должен перенаправить пакет через соединение с величиной MTU, меньшей размера IP-пакета, отбрасывать его и отправлять хосту-отправителю сообщение ICMP "Destination is unreachable" с кодом 4, что означает "Хост недоступен; требуется фрагментация». В этом же ICMP-сообщении процедура PMTUD указывает размер MTU следующего участка сетевого пути, по которому данный пакет не смог быть передан. Хост-отправитель, получив это сообщение ICMP, передает значение MTU модулю ТСР, который вычисляет новое значение MSS, соответственно уменьшает до указанного значения размер сегмента и пересылает его еще раз. Очевидно, что такая процедура достаточно быстро определит приемлемый размер MSS сетевого пути, и последующие пакеты по установленному соединению будут доходить до хоста-получателя без фрагментации.

Все операционные системы с 1988 года поддерживают процедуру PMTUD. Однако, ее применение может столкнуться с, так называемой, проблемой Path MTU Discovery Black Hole (RFC 2923, 1999). Ее источником являются чрезмерная осторожность некоторых администраторов, блокирующих отправку маршрутизаторами ICMP пакетов, включая и сообщения ICMP 3:4. Как итог - соединение между хостами устанавливается, но пакеты данных, которые формируются размером большим, чем неизвестный отправителю в такой ситуации MSS пути, и отправляются с установленным флагом DF, будут отбрасываться где-то по пути.

Сегмент SYN может содержать опцию масштабирования окна, являющуюся предложением использовать окно большего размера.

В SYN-сегменте может находиться и опция timestamp. Сторона, осуществляющая активное открытие соединения, может «предложить» использование этой опции посредством задания поля TSval в своем SYN-сегменте. Это предложение будет принято, если и другая сторона в своем SYN-сегменте заполнит поле TSval.

Фаза передачи данных

Предоставление приложениям сервиса надежной доставки данных в протоколе ТСР обеспечивается механизмом скользящего окна и процедурой ARQ с возвратом на N (обязательный режим) и с выборочным повторением (опционально, в современных реализациях протокола). Протокол также обеспечивает управление потоком в фазе передачи данных посредством изменения величины объявляемого окна и величины окна передачи. Рис. 6.20. иллюстрирует процесс управления потоком в фазе передачи данных.

 
 Фаза установления соединения - Инвестирование - 2


Пусть в момент t0 ТСР-модуль хоста Б объявил величину своего окна приема равной 2048 байт и номер старшего подтвержденного байта 2000-1. Такой размер окна позволяет TCP-передатчику хоста А отправить без подтверждения 2 Кбайта данных, однако в его выходном буфере имеется лишь 1024 байт (либо его MSS <=1024). Хост А отправляет эти данные нумеруя байты начиная с 2000. Одновременно, он объявляет величину своего окна равной 1024 байта и подтверждает, что номер ожидаемого первого байта от хоста Бдолжен быть равен 1. Хост Бзадерживает выдачу подтверждения на прибывший сегмент данных, полагая, что у него появятся данные для отправки хосту А, вместе с которыми он отправит и подтверждение. Тем временем, в момент t2 модуль ТСР хоста А снова получил от своего приложения 1024 байт данных и передал их хосту Б . После этого величина окна передачи на хосте А стала равной нулю и дальнейшая отправка им данных до получения подтверждения от хоста Б оказывается невозможной. В момент t3 модуль ТСР хоста Б получил 128 байт данных для отправки; вместе с ними он отправляет подтверждение получения двух сегментов данных, указывая Ack_no=4048. К этому моменту в буферной памяти модуля ТСР хоста Б оказывается свободными лишь 512 байт, поэтому он объявляет величину своего окна приема равной 512. Когда хост Аполучит этот сегмент, он, несмотря на то, что в момент t4 в его буфере имеется 2048 байт данных, сможет отослать только 512 байт и не перегрузит буфер хоста Б .

Когда отправитель получает сегмент, в котором значение объявленного окна (окна приема) равно нулю, он прекращает передачу данных и ждет следующий сегмент от принимающей стороны, в котором величина этого окна будет ненулевой. Этим следующим сегментом может быть сегмент ACK на ранее отправленные в противоположном направлении данные, либо собственно данные, отправляемые приемной стороной в обратном направлении. Но протокол TCP должен предпринять самостоятельно определенные действия в том случае, если приемная сторона не имеет данных для отправки, или сегмент-подтверждение, с отличным от нуля окном, был потерян. Напомним, что сегменты-подтверждения передаются ненадежно, т.е. TCP не подтверждает сами подтверждения. В такой ситуации на каждом конце соединения будут ждать действий от удаленной стороны: приемник ожидает получить данные (так как он отправил передающей стороне ненулевое окно), а отправитель ждет сообщение об обновлении окна, которое позволит ему продолжить передачу. Чтобы предотвратить подобную тупиковую ситуацию, отправитель использует специальный (persist) таймер, который инициализирует периодический опрос получателя о размере его окна приема. Сегменты, которые при этом посылает отправитель, называются window probes. Они содержит 1 байт данных (TCP всегда позволяет послать 1 байт данных, после того как окно было закрыто). Если подтверждения этих сегментов возвращаются с размером окна равным 0, то отправленный байт считается не подтвержденным. Значения persist таймера удваиваются при каждой последующей отправке сегмента window probes и достигнув максимального значения (60 сек) далее не изменяются. TCP не прекращает отправку сегментов window probes до тех пор, пока окно не будет открыто, или приложение решит, что соединение должно быть разорвано.

Предыдущее рассмотрение показывает, что задержка отправки подтверждения позволяет более экономно использовать пропускную способность канала. Это особенно актуально в ситуациях, подобных login-сессиям, когда пользователь вводит свои аутентификационные данные по одному символу. Пересылка каждого из них, сама по себе весьма затратная (на один байт информации приходится не менее 40 байтов заголовков TCP и IP уровней), а выдача подтверждения на каждый такой сегмент еще более усугубляет ситуацию. Решение, экономящее пропускную способность канала связи, было предложено Нейглом (Nagle). Идея алгоритма достаточно проста. Когда интерактивное приложение требует отсылки символа, модуль ТСР отправляет его и ждет подтверждения. Поступающие в этот период времени от приложения символы не передаются, а буферизируются; они отправляются все вместе в одном сегменте после получения подтверждения на первый отправленный символ. Однако, в локальных сетях, где задержки доставки сегментов относительно малы и каналы связи являются достаточно скоростными, применение рассмотренного алгоритма нецелесообразно.

Существует еще одна ситуация, в которой механизм регулирования окна протокола ТСР может приводить к неэффективному использованию полосы пропускания каналов связи. Пусть передающее приложение имеет большой объем данных для передачи, а принимающее приложение может читать буфер своего ТСР модуля лишь небольшими порциями. Ясно, что, в конце концов, это приведет к объявлению приемным модулем малого значения окна; соответственно, передающий модуль будет формировать сегменты с малым объемом данных, что и увеличит «накладные» расходы протокола при их передаче. Это явление часто называют «синдромом ленивого окна». Для уменьшения его негативного влияния ограничивают возможность объявлять малые значения приемного окна. А именно, пока размер свободного буферного пространства приемника не достигнет половины его объема, либо половины размера максимально допустимого сегмента, размер приемного окна не объявляется (т.е. считается равным нулю). Данные приложения на передающей стороне буферизируются и отправляются после объявления приемного окна достаточно большого размера.

Рассмотрим еще раз проблему зацикливания нумерующей последовательности, характерную для работы протокола ТСР в высокоскоростных средах. Исходная спецификация протокола предполагала, что время жизни IP-пакета не превышает 2 минуты. Последовательность из 232 номеров способна пронумеровать 4294967296 байт. Для их передачи по линии с пропускной способностью 2048 Кбит/с потребуется (232 х 8)/(2,048х106) = 4,5 часа, а по линии ОС-48 (2,4 Гбит/с) всего 14 секунд. Поэтому на современных высокоскоростных линиях механизм ARQ протокола TCP может столкнуться с проблемой неразличимости дублей. Как отмечалось выше, решение проблемы было найдено заданием 4-х байтовой временной метки, что объединило два способа разметки последовательности сегментов и период нумерующей последовательности увеличился до 264. Для реализации этого механизма таймер временных меток должен изменять свое значение, по крайней мере, один раз за время необходимое для отправки 232 байт (максимальное значение в поле номера сегмента). Это требование определяет нижнюю границу частоты таймера временных меток. Эта частота не должна быть и настолько высокой, чтобы полный цикл показаний таймера был пройден за время, меньшее максимального времени жизни сегмента. Значения порядка 1 кГц удовлетворяют этим ограничениям. Например, при частоте в 1кГц протокол будет успешно работать на линиях с пропускной способностью до 4 Тбит/с. [RFC 1323].

Похожие статьи