Как уже было отмечено ранее, главная задача транспортного уровня заключается в передаче данных между прикладными процессами. Эту задачу решают протокол управления передачейTCP (Transmission Control Protocol) и протокол пользовательских дейтаграмм UDP (User Datagram Protocol). Протоколы TCP и UDP имеют много общего. Тот и другой обеспечивают интерфейс с вышележащим прикладным уровнем, передавая данные, поступающие на входной интерфейс хоста, соответствующему приложению. При этом оба протокола используют концепции «порт» и «сокет». Оба они также поддерживают интерфейс с нижележащим сетевым уровнем IP, упаковывая свои пакеты в IP-пакеты.
Каждый компьютер может выполнять несколько процессов; более того, прикладной процесс тоже может иметь несколько точек входа, выступающих в качестве адреса назначения для пакетов данных. Поэтому после того, как пакет средствами протокола IP доставлен на сетевой интерфейс компьютера-получателя, данные необходимо переправить конкретному процессу-получателю.
|
|
Существует и обратная задача: пакеты, которые отправляют в сеть разные приложения, работающие на одном конечном узле, обрабатываются общим для них протоколом IP. Следовательно, в стеке должно быть предусмотрено средство «сбора» пакетов от разных приложений дляпередачи протоколу IP. Эту работу выполняют протоколы TCP и UDP.
Процедура приема протоколами TCP и UDP данных, поступающих от нескольких различных прикладных служб, называется мультиплексированием. Обратная процедура – процедура распределения протоколами TCP и UDP поступающих от сетевого уровня пакетов между набором высокоуровневых служб – называется демультиплексированием [11].
Протоколы TCP и UDP ведут для каждого приложения две очереди: очередь пакетов, поступающих к данному приложению из сети, и очередь пакетов, отправляемых данным приложением в сеть. Пакеты, поступающие на транспортный уровень, организуются операционной системой в виде множества очередей к точкам входа различных прикладных процессов. В терминологии TCP/IP такие системные очереди называются портами, причем входная и выходная очереди одного приложения рассматриваются как один порт. Для однозначной идентификации портов им присваивают номера, которые используются для адресации приложений [12].
Если процессы представляют собой популярные общедоступные службы (например, FTP, telnet, HTTP, DNS и т. п.), то за ними закрепляются стандартные, назначенные номера, также называемые хорошо известными (well-known) номерами портов. Эти номера закрепляются и публикуются в стандартах Интернета RFC. Так, номер 21 закреплен за службой удаленного доступа к файлам FTP, a 23 – за службой удаленного управления telnet. Назначенные номера являются уникальными в пределах Интернета и выделяются приложениям централизованноиз диапазона от 0 до 1023.
|
|
Для тех приложений, которые еще не стали столь распространенными, чтобы закреплять за ними стандартные номера, номера портов назначаются разработчиками этих приложений или операционной системой локальнов ответ на поступление запроса от приложения. На каждом компьютере операционная система ведет список занятых и свободных номеров портов. При поступлении запроса от приложения, выполняемого на данном компьютере, операционная система выделяет ему первый свободный номер. Такие номера называют динамическими [31].
В дальнейшем все сетевые приложения должны адресоваться к данному приложению с указанием назначенного ему номера порта. После того как приложение завершит работу, выделенный ему локальный номер порта возвращается в список свободных и может быть назначен другому приложению. Динамические номера являются уникальными в пределах каждого компьютера, но при этом обычной ситуацией является совпадение номеров портов приложений, выполняемых на разных компьютерах. Как правило, клиентские части известных приложений (DNS, WWW, FTP, telnet и др.) получают динамические номера портов от операционной системы.
Нет никакой зависимости между назначением номеров для приложений, использующих протокол TCP, и приложений, работающих с протоколом UDP. Приложения, которые передают данные на уровень IP по протоколу UDP, получают номера, называемые UDP-портами. Аналогично приложениям, обращающимся к протоколу TCP, выделяются ТСР-порты.
В том и другом случаях это могут быть как назначенные, так и динамические номера. Диапазоны чисел, из которых выделяются номера TCP- и UDP-портов, совпадают: от 0 до 1023 для назначенных и от 1024 до 65535 для динамических. Однако никакой связи между назначенными номерами TCP- и UDP-портов нет. Даже если номера TCP- и UDP-портов совпадают, они идентифицируют разные приложения. Например, одному приложению может быть назначен ТСР-порт 1750, а другому – UDP-порт 1750. В некоторых случаях, когда приложение может обращаться по выбору к протоколу TCP или UDP (например, таким приложением является DNS), ему, исходя из удобства запоминания, назначаются совпадающие номера TCP- и UDP-портов (в данном примере – это номер 53) [22].
2.5.1 Протокол UDP
Единица данных протокола UDP называется UDP-дейтаграммой, или пользовательской дейтаграммой. Каждая дейтаграмма переносит отдельное пользовательское сообщение. Это приводит к естественному ограничению: длина дейтаграммы UDP не может превышать длины поля данных протокола IP, которое, в свою очередь, ограничено размером кадра технологии нижнего уровня. Поэтому если UDP-буфер переполняется, то данные приложения отбрасываются.
Заголовок UDP, состоящий из четырех 2-х-байтовых полей, содержит номера портов отправителя и получателя, контрольную сумму и длину дейтаграммы (рис.2.11) [24].
16 бит Порт источника | 16 бит Порт приемника |
16 бит Длина дейтаграммы | 16 бит Контрольная сумма |
Рис. 2.11 – Структура UDP-заголовка
Поле Порт источника (Source Port) занимает 2 байта и идентифицирует процесс-отправитель.
Поле Порт приемника (Destination Port) занимает 2 байта и идентифицирует процесс-получатель.
Поле Длина дейтаграммы (Total Length) занимает 2 байта и представляет собой длину UDP-пакета вместе с заголовком.
Поле Контрольная сумма (Checksum) занимает 2 байта.
Ниже приведен пример заголовка UDP с заполненными полями:
1. Source Port = 0x0035 [порт источника].
2. Destination Port = 0x0411 [порт назначения].
3. Total length = 132 (0x84) bytes [длина UDP-заголовка].
4. Checksum = 0x5333 [контрольная сумма].
В этой UDP-дейтаграмме в поле данных, длина которого, как следует из заголовка, равна 132 байтам, помещено сообщение DNS-сервера. Это можно видеть по номеру порта источника (Source Port = 0x0035), что в шестнадцатеричном формате равно стандартному номеру DNS-сервера 53.
|
|
Протокол UDP решает задачу демультиплексирования следующим образом: кадры, несущие UDP-дейтаграммы, пребывают на сетевой интерфейс хоста, последовательно обрабатываются протоколами стека и поступают в распоряжение протокола UDP, который извлекает из заголовка номер порта назначения и передает данные на определенный порт соответствующему приложению, то есть выполняет демультиплексирование.
Это решение выглядит очень логично и просто, однако оно неработоспособно в ситуации, когда на конечном узле выполняется несколько копий одного и того же приложения. Пусть, например, на одном хосте запущены два DNS-сервера, причем оба используют для передачи своих сообщений протокол UDP. DNS-сервер имеет хорошо известный UDP-порт 53. В то же время у каждого из DNS-серверов могут быть свои клиенты, собственные базы данных и настройки. Когда на сетевой интерфейс данного компьютера придет запрос от DNS-клиента, в UDP-дейтаграмме будет указан номер порта 53, который в равной степени относится к обоим DNS-серверам. Чтобы снять неоднозначность, используют следующий прием: разным копиям одного приложения, даже установленным на одном компьютере, присваивают различные IP-адреса. В данном примере DNS-сервер1 имеет IP-адрес IР1, а DNS-сервер2 – IP-адрес IР2. Таким образом однозначно определяет прикладной процесс в сети (а тем более в пределах компьютера) пара (IP-адрес, номер порта UDP), называемая UDP-сокетом (UDP socket), то есть протокол UDP выполняет демультиплексирование на основе сокетов [18].
2.5.2 Протокол TCP
Информация, поступающая к протоколу TCP от протоколов более высокого уровня, рассматривается протоколом TCP как неструктурированный поток байтов. Поступающие данные буферизуются средствами TCP. Для передачи на сетевой уровень из буфера «вырезается» некоторая непрерывная часть данных, которая называется сегментом, и снабжается заголовком.
|
|
Заголовок TCP-сегмента содержит значительно больше полей, нежели заголовок UDP (рис. 2.12), что указывает на широту возможности первого протокола [27].
16 бит Порт источника | 16 бит Порт приемника | |||||||||
32 бита Последовательный номер | ||||||||||
32 бита Подтвержденный номер | ||||||||||
4 бита Длина заголовка | 6 бит Резерв | 6 бит Кодовые биты | 16 бит Окно | |||||||
URG | ACK | PSH | RST | SYN | F IN | |||||
16 бит Контрольная сумма | 16 бит Указатель срочности | |||||||||
максимум 24 бита Параметры | Заполнитель | |||||||||
Рис. 2.12 – Структура TCP-заголовка
Поле Порт источника (Source Port) занимает 2 байта и идентифицирует процесс-отправитель.
Поле Порт приемника (Destination Port) занимает 2 байта и идентифицирует процесс-получатель.
Поле Последовательный номер (Sequence Number) занимает 4 байта и представляет собой число, уникально идентифицирующее TCP-сегмент. Этот порядковый номер дает возможность получателям TCP-пакетов идентифицировать пропущенные части потока информации.
Поле Подтвержденный номер (Acknowledgement Number) занимает 4 байта и содержит максимальный номер байта в полученном сегменте, увеличенный на единицу. Именно это значение используется в качестве квитанции, то есть удостоверения, что сегмент получен. Если установлен контрольный бит АСК, то поле содержит следующий номер очереди, который отправитель данного сегмента желает получить в обратном направлении.
Поле Длина заголовка (Hlen) занимает 4 бита и представляет собой длину заголовка TCP-сегмента, измеренную в 32-х-битовых словах. Длина заголовка не фиксирована и может изменяться в зависимости от значений, устанавливаемых в поле параметров.
Поле Резерв (Reserved) занимает 6 бит.
Поле Кодовые биты (Code Bits) содержит служебную информацию о типе данного сегмента. Положительное значение сигнализируется установкой этих битов в единицу:
1) URG (срочность) – указывает на необходимость проверки значения поля Urgent Pointer (указатель срочности);
2) АСК (подтверждение) – указывает на необходимость проверки значения поля Acknowdgment Number (подтвержденный номер);
3) PSH (проталкивание) – игнорирует буферизацию и передает данные непосредственно прикладному уровню. Эта возможность применяется для приложений, выполняющихся однократно или с ограниченным временным ресурсом;
4) RST (сброс) – завершает соединение. Применяется для полного закрытия соединения, а также для отказа в соединении по любой причине;
5) SYN (синхронизация) – используется для синхронизации счетчиков переданных данных при установлении соединения и обозначает, что отправитель извещает противоположную сторону TCP-соединения о значении в своем поле Sequence Number (порядковый номер);
6) FIN (окончание) – обозначает, что хост завершил соединение, то есть достижение передающей стороной последнего байта в потоке передаваемых данных.
Поле Окно (Window) определяет размер TCP-буфера приема в байтах. Размер окна, приравненный к нулю, означает, что отправитель должен приостановить передачу – TCP-буфер получателя заполнен.
Поле Контрольная сумма (Сhecksum) занимает 2 байта.
Поле Указатель срочности (Urgent pointer) занимает 2 байта. Данное поле значимо только в том случае, если установить флаг URG, и получатель должен просмотреть это поле, чтобы узнать, откуда начинать считывать данные пакета.
Поле Параметры (Options) имеет переменную длину и может вообще отсутствовать. Максимальная величина поля составляет 3 байта; оно используется для решения вспомогательных задач, например для выбора максимального размера сегмента. Поле параметров может располагаться в конце заголовка TCP, а его длина кратна 8 битам.
Поле Заполнитель (padding) может иметь переменную длину. Это фиктивное поле, используемое для доведения размера заголовка до целого числа 32-х-битовых слов.
Основным отличием протокола TCP от UDP является то, что на протокол TCP возложена дополнительная задача – обеспечить надежную доставку сообщений, используя в качестве основы протокол IP.
TCP-протокол решает задачу обеспечения надежного обмена данными путем установления между компьютерами логических соединений, благодаря которым TCP следит, чтобы передаваемые сегменты не были потеряны, не были продублированы и пришли к получателю в том порядке, в котором были отправлены.
При установлении логического соединения модули TCP договариваются между собой о параметрах процедуры обмена данными. В протоколе TCP каждая сторона соединения посылает противоположной стороне следующие параметры:
1) максимальный размер сегмента, который она готова принимать;
2) максимальный объем данных (возможно несколько сегментов), которые она разрешает другой стороне передавать в свою сторону, даже если та еще не получила квитанцию на предыдущую порцию данных;
3) начальный порядковый номер байта, с которого она начинает отсчет потока данных в рамках этого соединения.
В результате переговорного процесса модулей TCP с двух сторон соединения определяются параметры соединения. Одни из них остаются постоянными в течение всего сеанса связи, а другие адаптивно изменяются. В частности, в зависимости от загрузки буфера принимающей стороны, а также от надежности работы сети динамически изменяется размер окна отправителя (размер буфера приема). Создание соединения означает выделение операционной системой на каждой стороне соединения определенных системных ресурсов для организации буферов, таймеров, счетчиков. Эти ресурсы будут закреплены за соединением с момента создания и до момента разрыва. Логическое TCP-соединение однозначно идентифицируется парой TCP-сокетов, каждый из которых одновременно может участвовать в нескольких соединениях.
Таким образом, из всего вышеизложенного о двух протоколах транспортного уровня стека TCP/IP следует, что на один из них – TCP – возложена сложная и очень важная задача обеспечения надежной передачи данных через ненадежную сеть.
С другой стороны, функциональная простота протокола UDP обусловливает простоту алгоритма его работы, компактность и высокую скорость. Поэтому те приложения, в которых реализован собственный, достаточно надежный механизм обмена сообщениями, основанный на установлении соединения, предпочитают использовать для непосредственной передачи данных по сети менее надежные, но более быстрые средства транспортировки, в качестве которых по отношению к протоколу TCP и выступает протокол UDP.
Протокол UDP может быть использован и в том случае, когда хорошее качество линий связи обеспечивает достаточный уровень надежности и без применения дополнительных приемов (например, установление логического соединения и квитирования передаваемых пакетов (подтверждение получения)). Заметим, что, поскольку протокол TCP основан на логических соединениях, он не годится для широковещательной и групповой рассылки, в отличие от протокола UDP.