Протоколы управления. Адресация в Internet. Базовые утилиты тестировая сетей TCP/IP.

Адресация в Internet

Узлы сетей, входящих в Internet, используют, по крайней мере, три системы адресации: локальную (адреса канального уровня, т.е., например, MAC-адреса в локальной Ethernet-сети), сетевую (IP-адреса) и символьную (доменные имена, DNS-имена).

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

Сетевой уровень стека TCP/IP передает пакеты между сетями, опираясь на IP-адреса (RFC 990 и RFC 997). IP-адрес (четвертой версии, являющейся основной в настоящее время) состоит из 32 бит (4 байт). Как правило, IP-адрес записывают как четыре десятичных числа (значения отдельных байтов), разделенные точками, например: 123.45.67.89. Адрес состоит из двух частей: номера подсети и номера узла, причем номер узла не зависит от его MAC-адреса (или другого локального адреса). Распределение номеров подсетей для Internet осуществляется централизованно (долгое время только InterNIC, потом ICANN, в скором времени — группа независимых организаций), а для внутренних подсетей, не связанных напрямую с Internet, может назначаться администратором сети.

Все IP-адреса разделены на 5 классов (от A до E), задающих разные соотношения между количеством подсетей и количеством узлов в них. На риc. 1 показана структура адресов разных классов (буквой N обозначены биты адреса, составляющие номер сети, буквой H — биты адреса, составляющие номер узла в сети, буквой M — биты адреса, составляющие номер группы рассылки).

Рис. 1. Классы IP-адресов.

Некоторые IP-адреса интерпретируются специальным образом:

— адрес, все биты которого равны нулю, обозначает адрес того узла, который выдал этот пакет; - адрес, в поле номера сети которого стоят только нули, считается относящимся к той же

сети,что и узел,выдавший этот пакет;

— адрес,все биты которого равны единице,означает,что данный пакет должны получить все узлы подсети, к которой относится узел, выдавший этот пакет (ограниченное широковещательное сообщение, англ. limited broadcast);

— адрес, в котором все биты поля номера узла равны единице, а поле номера сети задает определенную сеть (не все нули и не все единицы), то такой пакет должен рассылаться всем узлам указанной подсети (широковещательное сообщение,англ. broadcast).

Таким образом, ни номер подсети, ни номер узла не может состоять из одних нулей или одних единиц. Это ограничивает количество узлов в подсети соотношением: Hузлов = 2n –2, где n — количество бит в поле номера узла, а количество подсетей — соотношением: Nподсетей = 2m –2, где m — количество бит в поле номера подсети.

Например, каждая из 16382 (214 –2) подсетей класса B (14 бит под номер подсети, 16 бит под номер узла) максимально может включать 65534 (216 –2) узла с номерами от x.x.0.1 до x.x.255.254. Кроме того, выделяется группа адресов, первый байт которых равен 127. Эти адреса используются для передачи данных между процессами на одном компьютере или для тестирования. Данные, отправленные по такому адресу, рассматриваются, как только что принятые из сети, в результате чего образуется как бы “петля” (англ. loopback). Обычно используется адрес 127.0.0.1, но для этих целей можно использовать любой адрес вида 127.x.x.x.

Три блока IP-адресов зарезервированы для внутреннего использования в корпоративных сетях, отделенных от Интернета маршрутизаторами с функцией трансляции сетевых адресов NAT (англ. Network Address Translation), описанной в RFC 1631. Это одна подсеть класса А (адреса с 10.0.0.0 по 10.255.255.255), 16 подсетей класса B (адреса с 172.16.0.0 по 172.31.255.255) и 256 подсетей класса C (адреса с 192.168.0.0 по 192.168.255.255). Такие адреса называются «частными» (англ. private). Маршрутизаторы Интернета не должны маршрутизировать пакеты с такими адресами получателя.


Маска подсети

При классовой адресации определить, сколько бит адреса отведено под номер подсети, а сколько — под номер узла в подсети, можно по самому адресу (его старшим битам). Чтобы выделить эти номера из IP-адреса, можно, например, использовать 32-битовую маску, в которой старшие биты, соответствующие номеру подсети, выставлены в 1, а остальные — в 0. Тогда номер подсети выделяется операцией побитового И над адресом и маской, а номер узла — той же операцией над адресом и инвертированной маской. Такая битовая маска называется в TCP/IP маской подсети (англ. subnet mask); их принято записывать так же, как IP-адреса: четыре десятичных значения байтов, разделенных точками. Каждому классу соответствует фиксированная маска: классу А — 255.0.0.0, классу B — 255.255.0.0, классу C — 255.255.255.0. Сначала маски использовались только внутри программных модулей, реализующих сетевые протоколы, но со временем стали при IP-адресе указывать его маску подсети практически всегда.

Если организация получила в пользование некоторую подсеть, то она может распоряжаться всеми возможными значениями поля номера узла по своему желанию. Можно, например, продолжить идею разделения на подсети внутрь этого поля: разбить его на две части — номер подподсети и номер узла в подподсети. Такое разбиение может оказаться удобным, если у организации несколько локальных сетей и было бы желательно, чтобы можно было по IP-адресу видеть, к какой локальной сети (т.е. подподсети) относится данный компьютер. При обычной классовой адресации нет возможности указать, где проходит граница между номером подподсети и номером узла в ней. Использование масок подсети позволяет реализовать такое разбиение очень просто: если при адресе всегда передается маска подсети, то ничто не мешает считать номером узла только биты адреса, соответствующие нулевым битам маски, а остальные биты, которые в соответствии с классом адреса тоже относятся к номеру узла, считать номером подподсети. Например, адресу 192.153.99.210 с маской 255.255.255.224 соответствует подсеть класса C 192.153.99, подподсеть 6, узел 18 (т.к. третий байт маски «224» равен 11100000, следовательно номеру узла будут соответствовать последние пять бит IP-адреса 21010=11010010) Поскольку маска подсети всегда имеет одинаковую структуру: старшие биты — 1, младшие — 0, вместо четырех байт маски достаточно хранить и передавать всего один байт (реально хватило бы четырех бит) — количество старших единичных бит: например, маске 255.255.255.224 соответствует суффикс подсети /19.

При нумерации подподсетей и узлов них необходимо соблюдать те же правила, что и для обычных подсетей: все нули и все единицы в номере подподсети и в номере узла используются только для служебных целей. Таким образом, при разбиении на подподсети часть адресного пространства подсети расходуется впустую.

Использование классовой адресации привело к очень неравномерному распределению адресного пространства: например, половина все возможных адресов — адреса класса A — зарезервирована за 127 подсетями, которые заведомо не используют все эти адреса. В то же время сети класса C стали дефицитом уже в середине 1990-х годов. Решением этой проблемы стала бесклассовая адресация. При бесклассовой адресации старшие биты адреса перестают нести особый смысл, а границу между номером подсети и номером узла определяет маска (или суффикс) подсети. Старые классовые адреса при этом сохраняются (с соответствующими масками).


Протокол IP

Протокол IP (англ. Internet Protocol, протокол межсетевого взаимодействия) описан в RFC 791. Основная функция протокола IP — передача пакетов между узлами, принадлежащими к разным подсетям, через промежуточные подсети. Каждый пакет (дейтаграмма, англ. datagram) обрабатывается независимо от других. Доставка дейтаграмм не гарантируется. Возможны потери дейтаграмм, доставка с ошибками, дублирование и нарушение порядка следования. Вторая функция протокола IP — выполнение фрагментации пакетов при передаче их между сетями с разным максимально допустимым размером поля данных кадра (англ. Maximum Transfer Unit, MTU).

Существенное свойство протокола IP состоит в нетрадиционном порядке передачи битов: байт передается, начиная со старшего бита. Кроме того, нумерация битов в байте также начинается со старшего: самый старший бит имеет номер 0, самый младший — номер 7.

Дейтаграмма (IP-пакет) состоит из заголовка и поля данных. Формат заголовка приведен на рис. 2.

Рис. 2. Формат заголовка IP-пакета.

Поле Номер версии (англ. Version) [4 бита] — указывает используемый формат заголовка. В настоящее время основная используемая версия имеет номер 4.

Поле Длина заголовка (англ. Internet Header Length, IHL) [4 бита] — длина заголовка в четырехбайтовых словах, минимальное допустимое значение — 5 (соответствует длине заголовка в 20 байт). Максимальная длина заголовка — 60 байт.

Поле Тип сервиса (англ. Type of Service) [8 бит] — указывает на желаемые параметры качества обслуживания. Формат байта Типа сервиса приведен на рис. 3.

Рис. 3. Структура поля «Приоритет» заголовка IP-пакета.

Поле Приоритета (англ. Precedence) для обычных пакетов равно 0, остальные значения (от 1 до 7) используются для служебных целей, чем больше значение, тем выше приоритет. Поля D (англ. Delay, задержка), T (англ. Throughput, пропускная способность) и R (англ. Reliability, надежность) используются для указания наиболее важного для передающего узла параметра качества. Выбор происходит между малой задержкой, большой пропускной способностью и высокой надежностью. Соответствующий бит (биты) устанавливается в 1,остальные — в 0. Как правило, улучшение одного из параметров связано с ухудшением остальных.

Поле Общая длина (англ. Total Length) [16 бит] — длина дейтаграммы(заголовка и данных) в байтах. Хотя размер поля позволяет создавать дейтаграммы длиной до 65535 байт, стандарт требует, чтобы любой узел мог принимать, как минимум, 576-байтовые дейтаграммы (как целиком, так и частями), а отправлять дейтаграммы большей длины только, будучи уверенным, что получатель может их принять. Значение 576 выбрано, чтобы можно было передавать в одном IP-пакете 512 байт данных («блок данныхразумного размера», как написано в стандарте; отметим, что 512 байт — этотипичный размер сектора жесткого или гибкого диска), оставляя 64 байта подзаголовки протоколов: IP-заголовок занимает от 20 до 60 байт.

Поле Идентификация (англ. Identification) [16 бит] — значение, одинаковое для всех дейтаграмм, содержащих фрагменты одного пакета(«большого пакета»).

Поле Флаги (англ. Flags) [3 бита] — флаги, управляющие фрагментированием: 0 бит — зарезервирован, должен быть равен 0;1 бит (DF, англ. Don’t Fragment) — «0» = можно фрагментировать,«1» = нельзя фрагментировать;2 бит (MF, англ. More Fragments) — «0» = последний фрагмент,«1» = еще будут фрагменты.

Поле Смещение фрагмента (англ. Fragment Offset) [13 бит] — указываетна место в «большом пакете», с которого начинаются данные текущей дейтаграммы. Измеряется в 64-битовых (8-байтовых) словах. Например, Смещение фрагмента, равное двум, означает, что данные текущей дейтаграммы должны находиться в «большом пакете», начиная с 16-го байта. Первый фрагмент имеет нулевое смещение.

Поле Время жизни (англ. Time to Live, TTL) [8 бит] — максимальное время, которое дейтаграмма может находиться в сети. Каждый маршрутизатор должен уменьшать это значение на единицу, и отбрасывать дейтаграммы со значением TTL = 0, передавая при этом отправителю соответствующее ICMP- сообщение. Наличие этого поля обеспечивает уничтожение «зациклившихся» или «заблудившихся» дейтаграмм. Поле TTL также позволяет ограничить дальность распространения дейтаграммы (это удобно, например, при одновременной передаче множеству абонентов) и является основой для работы утилиты traceroute.

Протокол (англ. Protocol) [8 бит] — указывает, данные какого протокола верхнего уровня передаются в дейтаграмме. Возможные значения этого поля стандартизованы (RFC «Assigned Numbers»), приведем некоторые из них: 1 — ICMP, 4 — IP, 6 — TCP, 17 — UDP, 89 — OSPF.

Поле Контрольная сумма заголовка (англ. Header Checksum) [16 бит] — контрольная сумма всех полей заголовка, вычисляемая как дополнение суммы всех 16-битовых слов заголовка (с нулевыми битами в поле контрольной суммы). Поскольку некоторые поля заголовка (например, время жизни) изменяются при передаче дейтаграммы через сеть, контрольная сумма пересчитывается каждым маршрутизатором. Если получена дейтаграмма с неверной контрольной суммой, такая дейтаграмма отбрасывается.

Поле Адрес отправителя (англ. Source IP Address) [32 бита] — IP-адрес отправителя дейтаграммы.

Поле Адрес получателя (англ. Destination IP Address) [32 бита] — IP-адрес получателя дейтаграммы.

Поле Опции (англ. Options) [переменная длина] — необязательное поле, может содержать данные о безопасности, маршрут дейтаграммы (при маршрутизации от источника) и т.д. В одной дейтаграмме может быть несколько опций, каждая из которых состоит из кода опции (1 байт), длины опции (1 байт) и байтов данных опции. Если для опции не нужны дополнительные данные, она состоит из одного байта — кода опции. Опции в настоящее время практически не используются.

Поле Дополнение (англ. Padding) — нулевые байты в таком количестве, чтобы размер заголовка был кратен 4 байтам.


Фрагментация IP-пакетов

На пути пакета от отправителя к получателю могут встречаться локальные и глобальные сети разных типов с разными допустимыми размерами полей данных кадров канального уровня (MTU). Так, например, сети Ethernet могут передавать кадры размером до 1500 байт, сети FDDI — до 4500 байт, в других сетях действуют свои ограничения. Протокол IP умеет передавать дейтаграммы, длина которых больше MTU промежуточной сети, за счет фрагментирования — разбиения «большого пакета» на некоторое количество частей (фрагментов), размер каждой из которых удовлетворяет промежуточную сеть. После того, как все фрагменты будут переданы через промежуточную сеть, они будут собраны на узле-получателе модулем протокола IP обратно в «большой пакет». Отметим, что сборку пакета из фрагментов осуществляет только получатель, а не какой-либо из промежуточных маршрутизаторов. Маршрутизаторы могут только фрагментировать пакеты, но не собирать их. Это связано с тем, что разные фрагменты одного пакета не обязательно будут проходить через одни и те же маршрутизаторы.

Для того чтобы не перепутать фрагменты разных пакетов, используется поле «Идентификация», значение которого должно быть одинаковым для всех фрагментов одного пакета и не повторяться для разных пакетов, пока у обоих пакетов не истекло время жизни.

При делении данных пакета, размер всех фрагментов, кроме последнего, должен быть кратен 8 байтам. Это позволяет отвести меньше места в заголовке под поле «Смещение фрагмента».

Второй бит поля «Флаги» (MF), если равен единице, указывает на то, что данный фрагмент — не последний в пакете.

Если пакет отправляется без фрагментации, флаг MF устанавливается в 0, а поле Смещение фрагмента — заполняется нулевыми битами.

Если первый бит поля «Флаги» (DF) равен единице, то фрагментация пакета запрещена. Если этот пакет должен быть передан через сеть с недостаточным MTU, то маршрутизатор вынужден будет

его отбросить (и сообщить об этом отправителю посредством протокола ICMP). Этот флаг используется в случаях, когда отправителю известно, что у получателя нет достаточно ресурсов по восстановлению пакетов из фрагментов.


Протокол ICMP

Протокол ICMP (Internet Control Message Protocol, Протокол Управляющих Сообщений Интернет) описан в RFC 792.

Он используется для сообщений об ошибках или нештатных ситуациях, передаваемых узлу-отправителю дейтаграммы узлом-получателем или промежуточным маршрутизатором.

Хотя сообщения ICMP вкладываются в поле данных IP-дейтаграммы, то есть ICMP как бы является протоколом более высокого уровня, чем IP, модуль обработки ICMP-сообщений входит в модуль, реализующий протокол IP.

Сообщения ICMP всегда начинаются с заголовка, состоящего из трех полей (см. рис. 4), за которым следуют данные об ошибке.

Рис. 4. Формат сообщения ICMP.

Поле Тип (англ. Type) [8 бит] — тип сообщения (см. таблицу 1).

Поле Код (англ. Code) [8 бит] — причина проблем с доставкой дейтаграммы (см. таблицы 1-4). Для остальных типов в поле Код записывается нулевое значение.

Поле Контрольная сумма (англ. Checksum) [16 бит] — контрольная сумма ICMP-сообщения (начиная с поля Тип), вычисляемая, как в протоколе IP.

Таблица 1. Типы сообщений ICMP.

Таблица 2. Коды сообщений ICMP для типа 3 (получатель недостижим).

Таблица 3. Коды сообщений ICMP для типа 5 (изменение маршрута).

Таблица 4. Коды сообщений ICMP для типа 11 (время жизни дейтаграммы истекло).


Базовые утилиты для тестирования сетей TCP/IP

Утилита Ping позволяет проверить существование указанного узла и измерить время передачи до него одного пакета (можно задавать разные размеры пакета для исследования промежуточных сетей). Эта утилита выполняет передачу ICMP-сообщения типа 8 (Echo request), на которое получатель должен ответить ICMP-сообщением типа 0 (Echo reply).

Утилита traceroute показывает последовательность узлов, через которые проходит пакет на пути к получателю. Реализовано это следующим образом: последовательно отправляются пакеты с возрастающим значением в поле TTL: 1,2,3 и т.д. Тот маршрутизатор, который уменьшит TTL до нуля, обязан будет отправить ICMP-сообщение типа 11 (Time exceeded). В результате будут получены такие ICMP-сообщения по очереди от всех маршрутизаторов на пути пакета к получателю. В различных ОС эта утилита реализована по-разному: в ОС семейства Windows отправляются ICMP-сообщения (подобно утилите ping), а в Linux/FreeBSD — UDP-сообщения.


Протоколы транспортного уровня

Функции транспортного уровня

Отправителем и получателем данных, передаваемых через сеть, с точки зрения транспортного уровня, является приложение (процесс). Как любая программа, процессы создаются и уничтожаются, на каждом узле может выполняться несколько процессов, а каждый процесс может иметь несколько точек подключения к сети. Такие логические точки (программно организуемые, как правило, в виде очередей сообщений) называются портами (англ. port). Номер порта однозначно идентифицирует процесс. Когда узел получает дейтаграмму транспортного уровня, он направляет ее прикладному процессу, используя номер порта, заданный при установлении связи.

Порты нумеруются положительными целыми 16-битовыми числами. Разные протоколы транспортного уровня нумерую свои порты независимо, то есть, например, порт 20 протокола TCP и порт 20 протокола UDP совершенно не связаны друг с другом.

Некоторые номера портов заданы стандартами. Эти номера выделяются организацией IANA (англ. Internet Assigned Numbers Authority). В настоящее время под стандартные порты отведен диапазон от 0 до 1023 (ранее — до 255).Остальные порты могут свободно использоваться прикладными процессами. Порты в диапазоне от 1024 до 5000 называются временными (англ. ephemeral). Назначение этих портов не стандартизовано, но IANA поддерживает информацию об их использовании. В таблице, представленной ниже, перечислены стандартные протоколы и порты.

Таблица 5. Cтандартные протоколы и порты.

Пара «порт — IP-адрес» называется (в терминологии TCP/IP) гнездом или сокетом (англ. socket) и однозначно указывает программный процесс, выполняющийся на одном из узлов в сети.


Протокол UDP

Протокол UDP (англ. User Datagram Protocol, Протокол пользовательских дейтаграмм) описан в RFC 768. Он предоставляет прикладным процессам простейшие услуги транспортного уровня. Две основные функции UDP — распределение дейтаграмм между процессами (на основании номеров портов) и контроль передачи пользовательских данных (не только заголовка, как в протоколе IP). Как и IP, UDP не гарантирует доставку и не поддерживает установку соединений.

Сообщение протокола UDP называется пользовательской дейтаграммой (англ. User datagram) и состоит из заголовка и пользовательских данных. Структура заголовка приведена на рис. 5. Сразу за заголовком идут пользовательские данные.

Рис. 5. Формат заголовка дейтаграммы UDP.

Если значение поля «Порт отправителя» не важно для получателя, в него можно записать нулевое значение.

В поле «Длина сообщения» записывается размер пользовательских данных в байтах.

Нулевое значение в поле «Контрольная сумма» означает, что контрольная сумма не вычислялась. Для расчета контрольной суммы к началу дейтаграммы приписывается псевдозаголовок, состоящий из пяти полей (см. рис. 6).

Рис. 6. Формат псевдозаголовка UDP для расчета контрольной суммы.

Если длина дейтаграммы нечетна, то к ее концу добавляют один байт с нулевым значением. Перед началом расчета в поле «Контрольная сумма» записывается нулевое значение. Затем вычисляется контрольная сумма (по тому же алгоритму, как и в протоколе IP), результат записывается в поле «Контрольная сумма», а псевдозаголовок отбрасывается.


Протокол TCP

Протокол TCP (англ. Transmission Control Protocol, Протокол управления передачей) описан в RFC 793. Он обеспечивает надежную передачу потока данных, используя сервис передачи дейтаграмм протокола IP. Пакеты, передаваемые протоколом TCP, называются сегментами. Каждый TCP-сегмент размещается в одном IP-пакете (а в каждом IP-пакете может находиться только один TCP-сегмент).

Надежность передачи обеспечивается при помощи нумерации байтов потока и подтверждений приема. Все байты исходного потока данных нумеруются (этот номер называется номером в последовательности (англ. sequence number)), и с каждым сегментом передается номер в последовательности его первого байта.

Поскольку два узла могут передавать два встречных потока данные по одному TCP-соединению, для передачи подтверждений одного потока используются сегменты встречного потока. В каждом сегменте передается номер в последовательности байта, который собирается принять данный узел.

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

Сегмент состоит из заголовка и поля данных. Формат заголовка сегмента TCP приведен на рис. 7.

Рис. 7. Формат заголовка TCP-сегмента.

Поле Порт отправителя (англ. Source port) и Порт получателя (англ. Destination port) [16 бит] — номера портов на узлах.

Поле Номер в последовательности (англ. Sequence Number) [32 бита] — номер в потоке первого байта данных этого сегмента. Если установлен управляющий бит SYN, то в этом поле содержится начальный номер в последовательности (англ. Initial Sequence Number, ISN) и первый байт данных сегмента имеет номер в потоке ISN+1.

Поле Номер подтверждения (англ. Acknowledgement number) [32 бита] — номер байта в потоке, ожидаемого отправителем данного сегмента. При этом должен быть установлен управляющий бит ACK.

Поле Смещение данных (англ. Data offset) [4 бита] — количество 32-битовых слов в заголовке TCP-сегмента. Минимальное значение поля — 5 (20-байтовый заголовок).

Поле Резерв (англ. Reserved) [6 бит] — должны быть заполнены нулями. Поле Биты управления (англ. Control bits) [6 бит] — от старшего к младшему:

- URG (англ. Urgent Pointer field significant) — принимать во внимание поле «Указатель срочности»;

- ACK (англ. Acknowledgement field significant) — принимать во внимание поле «Номер подтверждения»;

- PSH (англ. Push function) — сегмент был принудительно отправлен не дожидаясь заполнения данными;

- RST (англ. Reset the connection) — прервать связь;

- SYN (англ. Synchronize sequence numbers) — синхронизировать номера байтов в потоке; - FIN (англ. No more data from sender) — отправитель больше не будет передавать данные.

Поле Окно (англ. Window) [16 бит] — размер окна — количество байтов данных, начиная с указанного в поле «Номер подтверждения», которые отправитель данного сегмента готов принять.

Поле Контрольная сумма (англ. Checksum) [16 бит] — контрольная сумма всего сегмента (заголовка и данных), вычисляется по алгоритму протокола IP. Как и в UDP, перед вычислением контрольной суммы к сегменту приписывается псевдозаголовок (той же структуры, что и в UDP).

Поле Указатель срочности (англ. Urgent Pointer) [16 бит] — содержит номер первого байта, имеющего обычный статус срочности. При этом должен быть установлен управляющий бит URG.

Поле Опции (англ. Options) [переменный размер] — дополнительная служебная информация. Подобно опциям заголовка IP-дейтаграммы, имеют переменную длину и могут вообще отсутствовать.

Поле Выравнивание (англ. Padding) — поле, используемое для доведения размера заголовка до целого числа 32-битовых слов.


Установление соединения

Прежде, чем процессы смогут обмениваться данными по TCP, необходимо установить TCP-соединение (англ. session); при этом используется процедура трехэтапного приветствия (англ. three-way handshake):

Клиент генерирует случайное число, которое будет использовано в качестве ISN (т.е. клиент будет нумеровать отправляемые байты начиная с этого числа), и отправляет сегмент с установленным управляющим битом SYN и ISN в поле «Номер в последовательности».

Сервер, получив сегмент с управляющим битом SYN, сохраняет пришедший в нем ISN клиента, генерирует свой ISN как случайное число, начиная с которого он будет нумеровать отправляемые байты, и

отправляет сегмент с установленными управляющими битами SYN и АСК, своим ISN в поле «Номер в последовательности» и полученным от клиента ISN+1 в поле «Номер подтверждения».

Клиент, получив сегмент с управляющими битами SYN и ACK, сохраняет пришедший в нем ISN сервера и отправляет сегмент с установленным управляющим битами АСК, своим ISN в поле «Номер в последовательности» и полученным от сервера ISN+1 в поле «Номер подтверждения».

После того, как каждая из сторон получила ISN другой стороны и подтвердила его, по соединению можно передавать данные.

Отметим, что на SYN-сегмент расходуется одно значение номера в последовательности (равное ISN), хотя в нем не передаются байты пользовательских данных.


Разрыв соединения

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

Если одна из сторон больше не собирается передавать данные по соединению, она должна передать сегмент с установленным управляющим битом FIN. Получив такой сегмент, вторая сторона должна подтвердить его получение сегментом с установленным управляющим битом ACK. После этого один из пары каналов (тот, по которому передавался FIN-сегмент) считается закрытым. Второй канал закрывается аналогично (FIN-сегмент в одну сторону, ACK-сегмент в ответ), но по инициативе другой стороны. Соединение может быть наполовину закрытым сколь угодно долго.

Таким образом, для корректного разрыва соединения нужно передать четыре сегмента. Отметим, что, как и при установлении соединения, на каждый FIN-сегмент расходуется одно значение номера в последовательности, хотя в нем не передаются байты пользовательских данных.

Если один из компьютеров, установивших соединение, отключается от сети, не выполнив корректного разрыва соединения (например, при сбое ОС или при нарушении работы канала связи), то вторая сторона соединения разорвет соединение не сразу, а только после истечения достаточно длительного промежутка времени. Это дает возможность первому компьютеру продолжить обмен данными по этому соединению (например, после восстановления работоспособности канала связи).


Размер сегмента

При формировании TCP-сегментов желательно, чтобы они имели такой размер, чтобы несущие их IP-пакеты не нужно было фрагментировать. Это значит, что максимальный размер сегмента должен зависеть от того, по сетям каких технологий пролегает путь между двумя узлами, установившими TCP-соединение: если на этом пути встречаются сети с маленьким размером кадра (например, сети X.25 с размером кадра 512 байт), максимальный размер данных поля сегмента должен быть таким, чтобы размер IP-пакета (т.е. размер данных + размер TCP-заголовка (обычно 20 байт) + размер IP-заголовка (обычно 20 байт)), в котором он размещен, не превосходил минимальный размер кадра промежуточных сетей.

В любом случае, максимальный размер IP-пакета, несущего TCP-сегмент, не должен превышать максимального размера поля данных кадра сети, к которой непосредственно подключен узел. Например, для сетей Ethernet с максимальным размером поля данных кадра, равным 1500 байт (для кадров Ethernet II/DIX и 802.3), максимальный размер сегмента (англ. MSS, Maximum Segment Size) не должен превышать 1460 байт.

Если есть возможность увеличения MSS (например, известно, что обмен данными по TCP происходит только в локальной сети Ethernet), то ею не стоит пренебрегать: чем больше MSS, тем больше данных переносится в одном кадре, тем меньше накладные расходы и тем эффективнее передача данных.

По умолчанию (если в настройках TCP/IP не указано иное значение) размер сегмента равен 536 байт (поскольку максимальный размер IP-пакета по умолчанию равен 576 байт).


Окна приема

Протокол TCP имеет средства управления потоком данных: если принимающая данные сторона не успевает их обрабатывать, отправитель замедляет или приостанавливает передачу.

В процессе установки соединения каждая из сторон выделяет память под входной и выходной буферы и передает (в поле «Окно» того же SYN-сегмента, в котором передается ISN) второй стороне количество байт, которые она готова принять (не больше, чем размер своего входного буфера); это число в TCP называется окном приема (англ. receive window). Получив значение окна приема, вторая сторона сохраняет его в блоке управления передачей, связанном с соединением, и в процессе передачи данных следит за тем, чтобы объем отправленных, но неподтвержденных данных никогда не превышал размер окна приема.

В процессе передачи данных стороны могут изменять свои окна приема (размер окна приема передается в каждом сегменте в поле «Окно»): например, если приемник перегружен, он может передать сегмент с полем «Окно», равным нулю (чтобы отправитель приостановил передачу), а когда перегрузка приемника закончится, передать сегмент с нормальным значением в поле «Окно».

В начале передачи данных, пока приемник и передатчик не уверены в качестве соединяющих их каналов связи, обычно обе стороны устанавливают небольшое окно приема (размером в один MSS). По мере того, как приходят подтверждения, размер окна увеличивается экспоненциально (после первого подтверждения — два MSS, после второго — четыре MSS, после третьего — восемь MSS и т.д.) до некоторого порога, после которого растет линейно (с каждым новым подтверждением окно увеличивается на один MSS). Если хотя бы один сегмент не подтвержден (или пришел сегмент с запросом повторной передачи), размер окна уменьшается вдвое с каждым неподтвержденным или перезапрошенным сегментом, пока сегменты не начнут снова подтверждаться. Дальше окно приема опять начинает расти.

Блок управления передачей и состояния соединения

Каждый раз при установлении соединения модуль TCP создает структуру данных — Блок управления передачей (англ. Transmission Control Block, TCB), хранящую постоянную информацию о соединении (IP-адреса, номера портов, указатели на входной и выходной буферы, очередь повторной отправки и т.д.) и текущие значения переменных, описывающих текущее состояние соединения. К этим переменным относятся:

— SND.UNA — не подтвержденная посылка;

— SND.NXT — следующий сегмент на отправку; - SND.WND — окно передачи;

— SND.UP — указатель срочности для отправляемых данных;

— SND.WL1 — номер в последовательности, использованный для последней коррекции окна; - SND.WL2 — номер подтверждения, использованный для последней коррекции окна;

— ISS — начальный номер в последовательности для отправки; - RCV.NXT — следующий сегмент, который можно принять; - RCV.WND — окно приема;

— RCV.UP — указатель срочности для принимаемых данных; - IRS — начальный номер в последовательности для приема.

Кроме того, значения некоторых полей заголовка текущего сегмента тоже переносятся в переменные TCB:

— SEG.SEQ — номер в последовательности; - SEG.ACK — номер подтверждения;

— SEG.LEN — длина сегмента; - SEG.WND — размер окна;

— SEG.UP— указатель срочности; - SEG.PRC — приоритет.

TCP-соединение в каждый момент времени находится в одном из следующих состояний:

— LISTEN (Прослушивание) — ожидание запроса на соединение;

— SYN-SENT (Синхронизация отправлена) — ожидание парного запроса на соединение (после того, как был отправлен запрос на соединение);

— SYN-RECEIVED (Синхронизация получена) — ожидание подтверждения после обмена запросами на соединение;

— ESTABLISHED (Установлено) — соединение установлено и может передавать пользовательские данные; основное рабочее состояние;

— FIN-WAIT-1 (Ожидание завершения 1) — ожидание запроса на завершение соединения или подтверждения своего запроса на завершение соединения;

— FIN-WAIT-2 (Ожидание завершения 2) — ожидание запроса на завершение соединения;

— CLOSE-WAIT (Ожидание закрытия) — ожидание запроса на закрытие соединения от своего прикладного процесса;

— CLOSING (Закрытие) — ожидание подтверждения запроса на закрытие соединения;

— LAST-ACK (Последнее подтверждение) — ожидание подтверждения запроса на закрытие соединения (в котором содержалось подтверждение запроса на закрытие соединения);

— TIME-WAIT (Ожидание) — пауза для уверенности, что дальняя сторона соединения получила подтверждение своего запроса на закрытие соединения

— CLOSED (Закрыто) — соединение закрыто.