Машина состояний для протокола tcp

машина состояний для протокола tcp - student2.ru

Рис. 4.4.3.4. Машина состояний для протокола TCP (W.R. Stivens, TCP/IP Illustrated. V1. Addison-Wesley publishing company. 1993. Имеется обновленная версия книги, переведенная на русский язык: У.Ричард Стивенс, "Протоколы TCP/IP. Практическое руководство", BHV, Санкт-Петербург, 2003)

Состояние TIME_WAIT часто называется ожиданием длительностью 2MSL (Maximum Segment Lifetime). Значение MSL задается конкретной реализацией и определяет предельную величину пребывания сегмента в сети. В RFC-793 рекомендуется задавать MSL равным 2 мин. Но нужно помнить, что ТСР-сегмент транспортируется в IP-дейтаграмме, содержащем поле TTL. Когда модуль выполнил активное закрытие и в ответ на FIN послал ACK, соединение должно оставаться в состоянии TIME_WAIT в течение времени, в два раза превышающем MSL. Сокет, используемый данным соединение не может быть задействован другим соединением в продолжении указанного времени. Все сегменты данного соединения, задержавшиеся в пути, во время TIMR_WAITотбрасываются. Это гарантирует то, что сегменты старого соединения не будут восприняты новым соедиением. Такая процедура препятствует перезапуску серверов в течение 1-4 минут, так как в течение данного времени не могут использоваться стандартные значения номеров портов.

Состояние FIN_WAIT_2 сопряжено со случаем, когда одна сторона послала сегмент FIN, а другая сторона подтвердила его получение. Если данное соединение не нужно, можно ждать, когда приложение другой стороны получит код конца файла и пришлет свой флаг FIN. Только после этого система перейдет из состояний FIN_WAIT_2 в состояние TIME_WAIT. Теоретически такое ожидание может быть бесконечным. Другая сторона при этом остается в состоянии CLOSE_WAIT, пока приложение не вызовет функцию close. Для решения проблемы часто вводят дополнительный таймер.

В ТСР возможна ситуация, когда обе стороны запускают процедуру закрытия одновременно (посылают FIN), что в протоколе ТСР вполне допустимо. Каждая из сторон при этом переходит из состояния ESTABLISHED в состояние FIN_WAIT_1 (после вызова операции closed). По получении FIN стороны переходят из состояния FIN_WAIT_1 в состояние CLOSING и посылают ACK. После получения ACK происходит переход в состояние TIME_WAIT.

Когда оператор, работая в диалоговом режиме, нажимает командную клавишу, сегмент, в который помещается эта управляющая последовательность, помечается флагом PSH (push). Это говорит приемнику, что информация из этого сегмента должна быть передана прикладному процессу как можно скорее, не дожидаясь прихода еще какой-либо информации. Сходную функцию выполняет флаг URG. URG позволяет выделить целый массив данных, так как активизирует указатель последнего байта важной информации. Будет ли какая-либо реакция на эту "важную" информацию определяет прикладная программа получателя. URG-режим используется для прерываний при работе с FTP, telnet или rlogin. Если до завершения обработки "важной" информации придет еще один сегмент с флагом URG, значение старого указателя конца "важного" сообщения будет утеряно. Это обстоятельство должно учитываться прикладными процессами. Так telnet в командных последовательностях всегда помещает префиксный байт с кодом 255.

Алгоритм Нагля

В режиме удаленного терминала (telnet/ssh) при нажатии любой клавиши формируется и поcылается 41-октетный сегмент (здесь не учитываются издержки Ethernet), который содержит всего один байт полезной информации. В локальной сети здесь проблем не возникает, но в буферах маршрутизаторов в среде Интернет могут возникнуть заторы. Эффективность работы может быть улучшена с помощью алгоритма Нагля (Nagle, 1984; RFC-896). Нагль предложил при однобайтовом обмене посылать первый байт, а последующие буферизовать до прихода подтверждения получения посланного. После этого посылаются все буферизованные октеты, а запись в буфер вводимых кодов возобновляется. Если оператор вводит символы быстро, а сеть работает медленно, этот алгоритм позволяет заметно понизить загрузку канала. Встречаются, впрочем, случаи, когда алгоритм Нагля желательно отключить, например, при работе в Интернет в режиме Х-терминала, где сигналы перемещения мышки должны пересылаться немедленно, чтобы не ввести в заблуждение пользователя относительно истинного положения маркера.

Синдром узкого окна

Существует еще одна проблема при пересылке данных по каналам TCP, которая называется синдром узкого окна (silly window syndrome; Clark, 1982). Такого рода проблема возникает в том случае, когда данные поступают отправителю крупными блоками, а интерактивное приложение адресата считывает информацию побайтно. Предположим, что в исходный момент времени буфер адресата полон и передающая сторона знает об этом (window=0). Интерактивное приложение считывает очередной октет из TCP-потока, при этом TCP-агент адресата поcылает уведомление отправителю, разрешающее ему послать один байт. Этот байт будет послан и снова заполнит до краев буфер получателя, что вызовет отправку ACK со значением window=0. Этот процесс может продолжаться сколь угодно долго, понижая коэффициент использования канала ниже паровозного уровня.

Кларк предложил не посылать уведомление о ненулевом значении ширины окна при считывании одного байта, а лишь после освобождения достаточно большого пространства в буфере. Например, когда адресат готов принять MSS байтов или когда буфер наполовину пуст.

Предполагается, что получатель пакета практически всегда посылает отправителю пакет-отклик. Отправитель может послать очередной пакет, не дожидаясь получения подтверждения для предшествующего. Таким образом, может быть послано k пакетов, прежде чем будет получен отклик на первый пакет (протокол "скользящего окна").

В протоколе TCP "скользящее окно" используется для регулировки трафика и препятствия переполнения буферов.

Идея скользящего окна отображена на рис. 4.4.3.5. Здесь предполагается, что ширина окна равна 7 (k=7; это число может меняться в очень широких пределах).

машина состояний для протокола tcp - student2.ru

Рис. 4.4.3.5. Схема использования скользящего окна

После прихода отклика на пакет <1> окно смещается вправо на одну позицию. Теперь отправитель может послать и пакет <8>. Если порядок прихода откликов нарушается, сдвиг окна может задержаться. Размер окна в сегментах определяется соотношением:

window > RTT×B/MSS,

где B - полоса пропускания канала в бит/с, а MSS - максимальный размер сегмента в битах, а window - в сегментах.

Для протокола TCP механизм скользящего окна может работать на уровне октетов или сегментов. В первом случае нужно учитывать каждый раз размер поля данных переданного и подтвержденного сегмента. В TCP-протоколе используется три указателя (стрелки на рис. 4.4.3.3б):

Первый указатель определяет положение левого края окна, отделяя посланный сегмент, получивший подтверждение, от посланного сегмента, получение которого не подтверждено. Второй указатель отмечает правый край окна и указывает на сегмент, который может быть послан до получения очередного подтверждения. Третий указатель помечает границу внутри скользящего окна между уже посланными сегментами и теми, которые еще предстоит послать. Получатель организует аналогичные окна для обеспечения контроля потока данных. Если указатель 3 совпадет с указателем 2, отправитель должен прервать дальнейшее отправление пакетов до получения хотя бы одного подтверждения. Обычно получатель посылает одно подтверждение (ACK) на два полученных сегмента.

Регулирование трафика в TCP подразумевает существование двух независимых процессов: контроль доставки, управляемый получателем с помощью параметра window, и контроль перегрузки, управляемый отправителем с помощью окна перегрузки cwnd (congestion window) и ssthreth (slow start threshold). Первый процесс отслеживает заполнение входного буфера получателя, второй - регистрирует перегрузку канала, а также связанные с этим потери и понижает уровень трафика. В исходный момент времени при установлении соединения cwnd делается равным одному MSS, а ssthreth=65535 байтам. Программа, управляющая пересылкой, никогда не пошлет больше байт, чем это задано cwnd и объявленным получателем значением window. Когда получение очередного блока данных подтверждено, значение cwnd увеличивается. Характер этого увеличения зависит от того, осуществляется медленный старт или реализуется процедура подавления перегрузки. Если cwnd меньше или равно ssthreth, выполняется медленный старт, в противном случае осуществляется подавление перегрузки. В последнем случае cwndi+1 = cwndi + MSS/8 +(MSS*MSS)/cwnd. Если возникает состояние перегрузки канала значение cwnd снова делается равным одному MSS.

Окно перегрузки (CWND) позволяет согласовать полную загрузку виртуального соединения и текущие возможности канала, минимизируя потери пакетов при перегрузке.

В качестве модуля приращения cwnd используется MSS. При получении подтверждения (ACK) окно перегрузки увеличивается на один сегмент ("медленный старт", CWNDi+1 = CWNDi + размер_сегмента, последнее слагаемое нужно, если размер окна задан в октетах, в противном случае вместо него следует использовать 1) и теперь отправитель может послать, не дожидаясь ACK, уже два сегмента и т.д.. Ширина окна, в конце концов, может стать настолько большой, что ошибка доставки в пределах окна станет заметной. Тогда будет запущена процедура “медленного старта” или другой алгоритм, который определит новое, уменьшенное значение окна. Окно перегрузки позволяет управлять информационным потоком со стороны отправителя, блокируя возможные перегрузки и потери данных в промежуточных узлах сети (о других методах подавления перегрузки канала смотри раздел "Сети передачи данных"). Если переполнения не происходит, CWND становится больше окна, объявленного получателем, и именно последнее будет ограничивать поток данных в канале. Размер окна, объявленный получателем, ограничивается произведением полосы пропускания канала (бит/с) на RTT (время распространения пакета туда и обратно). Максимально допустимый размер окна в TCP равен 65535 байт (задается размером поля). Конечной целью регулирования трафика является установление соответствия между темпом передачи и возможностями приема. Причиной перегрузки может быть не только ограниченность размера буфера, но и недостаточная пропускная способность какого-то участка канала. С учетом этого обстоятельства каждый отправитель формирует два окна: окно получателя и окно перегрузки (ширина этого окна равна cwnd). Каждое из этих окон задает число байтов, которое может послать отправитель. Реальное число байтов, которое разрешено послать, равно минимальному из этих окон. При инициализации соединения окно перегрузки имеет ширину равную максимальному сегменту, который может быть использован в данном канале. Отправитель посылает такой сегмент. Если будет прислано подтверждение до истечения времени таймаута, размер окна перегрузки удваивается и посылается два сегмента максимальной длины. При получении подтверждения доставки каждого из сегментов окно перегрузки увеличивается на один сегмент максимальной длины. Когда ширина окна перегрузки становится равной B сегментов и все B посланных сегментов получают подтверждение, окно перегрузки возрастает на число байт, содержащихся в этих сегментах. Таким образом, ширина окна перегрузки последовательно удваивается, пока доставка всех сегментов подтверждается. Рост ширины окна перегрузки при этом имеет экспоненциальный характер. Это продолжается до тех пор, пока не наступит таймаут или окно перегрузки не сравняется с окном получателя. Именно эта процедура и называется медленным стартом (Джекобсон, 1988).

Как было сказано выше, помимо окон перегрузки и получателя в TCP используется третий параметр - порог (иногда он называется порогом медленного старта ssthresh). При установлении соединения ssthresh=64 Kбайт. В случае возникновения таймаута значение ssthresh делается равным CWND/2, а само значение CWND приравнивается MSS (см. рис. 4.4.3.6). Далее запускается процедура медленного старта, чтобы выяснить возможности канала. При этом экспоненциальный рост cwnd осуществляется вплоть до значения ssthresh. Когда этот уровень cwnd достигнут, дальнейший рост происходит линейно с приращением на каждом шагу равным MSS (рис. 4.4.3.6).

Наши рекомендации