6.5. Транспортные протоколы Интернета: TCP
UDP является простым протоколом и имеет очень важную область применения. В первую очередь, это клиент-серверные взаимодействия и мультимедиа. Тем не менее большинству интернет-приложений требуется надежная, последовательная передача. UDP не удовлетворяет этим требованиям, поэтому необходим иной протокол. Такой протокол называется TCP, и он является рабочей лошадкой Интернета. Ниже мы рассмотрим его детально.
6.5.1. Основы TCP
Протокол TCP (Transmission Control Protocol — протокол управления передачей)
был специально разработан для обеспечения надежного сквозного байтового потока по ненадежной интерсети. Объединенная сеть отличается от отдельной сети тем, что ее различные участки могут обладать сильно различающейся топологией, пропускной способностью, значениями времени задержки, размерами пакетов и другими параметрами. При разработке TCP основное внимание уделялось способности протокола адаптироваться к свойствам объединенной сети и отказоустойчивости при возникновении различных проблем.
Протокол TCP был описан в RFC 793 в сентябре 1981 года. Со временем он был во многом усовершенствован, были исправлены различные ошибки и неточности. На сегодняшний день существует множество других RFC, являющихся дополнениями к RFC 793 (что позволяет судить о степени распространения этого протокола): уточнения и исправления описаны в RFC 1122, расширения для высокой производительности — в RFC 1323, выборочные подтверждения — в RFC 2018, контроль перегрузки — в RFC 2581, использование полей заголовка для качества обслуживания — в RFC 2873, усовершенствованные таймеры повторной передачи — в RFC 2988, явные уведомления о перегрузке — в RFC 3168. Поскольку это далеко не полный список, для удобной работы со всеми этими RFC был создан специальный указатель (конечно же, в виде еще одного RFC-документа) — RFC 4614.
Каждая машина, поддерживающая протокол TCP, обладает транспортной подсистемой TCP, являющейся либо библиотечной процедурой, либо пользовательским процессом, либо (чаще всего) частью ядра системы. В любом случае, транспортная подсистема управляет TCP-потоками и интерфейсом с IP-уровнем. TCP-подсистема принимает от локальных процессов пользовательские потоки данных, разбивает их на куски, не превосходящие 64 Кбайт (на практике это число обычно равно 1460 байтам данных, что позволяет поместить их в один кадр Ethernet с заголовками IP и TCP), и посылает их в виде отдельных IP-дейтаграмм. Когда IP-дейтаграммы с TCP-данными прибывают на машину, они передаются TCP-подсистеме, которая восстанавливает исходный байтовый поток. Для простоты мы иногда будем употреблять «TCP» для обозначения транспортной подсистемы TCP (части программного обеспечения) или протокола TCP (набора правил). Из контекста будет понятно, что имеется в виду. Например, в выражении «Пользователь передает данные TCP» подразумевается, естественно, транспортная подсистема TCP.
Уровень IP не гарантирует правильной доставки дейтаграмм и не накладывает ограничений на скорость их отправки. Именно TCP приходится выбирать правильную скорость отправки (следуя целям эффективного использования пропускной способности и предотвращения перегрузок), следить за истекшими интервалами ожидания и в случае необходимости заниматься повторной передачей дейтаграмм, не дошедших до места назначения. Бывает, что дейтаграммы прибывают в неправильном порядке. Восстанавливать сообщения из таких дейтаграмм обязан также TCP. Таким образом, протокол TCP призван обеспечить хорошую производительность и надежность, о которой мечтают многие приложения и которая не предоставляется протоколом IP.
6.5.2. Модель сервиса TCP
В основе сервиса TCP лежат так называемые сокеты (гнезда или конечные точки), создаваемые как отправителем, так и получателем. Они обсуждались в разделе 6.1.3. У каждого сокета есть номер (адрес), состоящий из IP-адреса хоста и 16-битного номера, локального по отношению к хосту, называемого портом. Портом в TCP называют TSAP-адрес. Для обращения к сервису TCP между сокетом одной машины и сокетом другой машины должно быть явно установлено соединение. Базовые операции сокетов приведены в табл. 6.2.
Один сокет может использоваться одновременно для нескольких соединений. Другими словами, два и более соединения могут оканчиваться одним сокетом. Соединения различаются по идентификаторам сокетов на обоих концах — (socketl, socket2). Номера виртуальных каналов или другие идентификаторы не используются.
Номера портов со значениями ниже 1024 зарезервированы стандартными сервисами и доступны только привилегированным пользователям (например, root в UNIX-системах). Они называются известными портами (well-known ports). Например, любой процесс, желающий удаленно загрузить почту с хоста, может связаться с портом 143 хоста-адресата и обратиться, таким образом, к его IMAP-демону. Список известных портов приведен на сайте www.iana.org. Таких портов на данный момент более 700. Некоторые из них включены в табл. 6.4.
Порты с номерами от 1024 до 49151 можно зарегистрировать через IANA для непривилегированных пользователей, однако приложения могут выбирать свои собственные порты (что они, как правило, и делают). К примеру, приложение BittTorrent для однорангового совместного доступа к файлам (неофициально) использует порты 6881-6887, однако другие порты также возможны.
Можно было бы, конечно, связать FTP-демона с портом 21 еще во время загрузки, тогда же связать демона SSH с портом 22 и т. д. Однако, если бы мы так сделали, мы бы только зря заняли память информацией о демонах, которые, на самом деле, большую часть времени простаивают. Вместо этого обычно пользуются услугами одного демона, называемого в UNIX inetd (Internet daemon), который связывается с несколькими портами и ожидает первое входящее соединение. Когда оно происходит, inetd создает новый процесс, для которого вызывается подходящий демон, обрабатывающий запрос. Таким образом, постоянно активен только inetd, остальные вызываются только тогда, когда для них есть работа. Inetd имеет специальный конфигурационный файл, из которого он может узнать о назначении портов. Это значит, что системный администратор может настроить систему таким образом, чтобы с самыми загруженными портами (например, 80) были связаны постоянные демоны, а с остальными — inetd.
Таблица 6.4. Некоторые зарезервированные порты
Порт
Протокол
Использование
20, 21
FTP
Передача файлов
22
SSH
Дистанционный вход в систему, замена Telnet
25
SMTP
Электронная почта
80
HTTP
Всемирная паутина (World Wide Web)
110
POP-3
Удаленный доступ к электронной почте
143
IMAP
Удаленный доступ к электронной почте
443
HTTPS
Защита от угроз (HTPP через SSL/TLS)
543
RTSP
Контроль воспроизведения мультимедиа
631
IPP
Коллективное использование принтера
Все TCP-соединения являются полнодуплексными и двухточечными. Полный дуплекс означает, что трафик может следовать одновременно в противоположные стороны. Двухточечное соединение подразумевает, что у него имеются ровно две конечные точки. Широковещание и многоадресная рассылка протоколом TCP не поддерживаются.
TCP-соединение представляет собой байтовый поток, а не поток сообщений. Границы между сообщениями не сохраняются. Например, если отправляющий процесс записывает в TCP-поток четыре 512-байтовых порции данных, эти данные могут быть доставлены получающему процессу в виде четырех 512-байтовых порций, двух 1024-байтовых порций, одной 2048-байтовой порции (рис. 6.30) или как-нибудь еще. Нет способа, которым получатель смог бы определить, каким образом записывались данные.