Опубликован: 22.06.2005 | Уровень: для всех | Доступ: платный
Лекция 14:

Сеть TCP/IP в Linux

Транспортный уровень

Транспортных протоколов в TCP/IP два – это TCP ( T ransmission C ontrol P rotocol, протокол управления соединением) и UDP ( U ser D atagram P rotocol). UDP устроен просто. Пользовательские данные помещаются в единственный транспортный пакет-датаграмму, которой приписываются обычные для транспортного уровня данные: адреса и порты отправителя и получателя, после чего пакет уходит в сеть искать адресата. Проверять, был ли адресат способен этот пакет принять, дошел ли пакет до него и не испортился ли по дороге, предоставляется следующему – прикладному – уровню.

Иное дело – TCP. Этот протокол очень заботится о том, чтобы передаваемые данные дошли до адресата в целости и сохранности. Для этого предпринимаются следующие действия:

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

    Перед тем, как начать передавать данные, TCP проверяет, способен ли адресат их принимать. Если адресат отвечает согласием на открытие соединения, устанавливается двусторонняя связь между ним и отправителем. Помимо адресов отправителя и адресата и номеров портов на отправителе и адресате, в TCP-соединении участвуют два номера последовательности (SEQuential Number, SEQN), с помощью которых каждая сторона проверяет, не потерялись ли пакеты по пути, не перепутались ли.
  2. Обрабатываются подтверждения

    Двусторонняя связь нужна еще и потому, что на каждый TCP-пакет с любой стороны требуется подтверждение того, что этот пакет принят. Упрощенно можно представить дело так, что отправитель и адресат по очереди обмениваются пакетами, каждый из которых содержит подтверждение только что принятого, и, возможно, полезные данные. Если происходит какая-то ошибка, она возвращается вместо подтверждения и отправитель обрабатывает ее (например, поcылает пакет еще раз).
  3. Отслеживаются состояния абонентов

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

Кажется, что TCP – протокол во всех отношениях более удобный, чем UDP. Однако в тех случаях, когда пользовательские данные всегда помещаются в один пакет, зато самих пакетов идет очень много, посылать всего одну датаграмму намного выгоднее, чем всякий раз устанавливать соединение, пересылать данные и закрывать соединение (что требует, как минимум, по три пакета в каждую сторону). Очень трудно использовать TCP для широковещательных передач, когда число абонентов-адресатов весьма велико или вовсе неизвестно. Посмотреть параметры всех передаваемых через сетевой интерфейс пакетов можно с помощью команды tcpdump -pi интерфейс, хотя Мефодию не хватило поверхностного знания TCP/IP для того, чтобы понять выдачу этой команды.

Прикладной уровень

Как бы ни был надежен протокол TCP, он не имеет никакого понятия о том, что же, собственно, за данные с его помощью передаются. Да и не должен: принцип разделения уровней не позволяет заглядывать "внутрь" передаваемого пакета, и способов наверняка распознать используемый в нем прикладной протокол нет. Прикладной уровень, в отличие от транспортного, предусматривает сколько угодно протоколов передачи данных. Интерпретация данных, в конце концов, дело уже не ядра, а какой-нибудь программы ("приложения", как правило, демона ). Для того чтобы можно было предположить, какой протокол используется при передаче данных, а также для того, чтобы система могла передать эти данные соответствующей программе, еще на транспортном уровне было введено понятие порта.

Клиент-серверная модель

С точки зрения прикладного уровня, порт – это идентификатор сервиса, предоставляемого системой. В самом деле, практически любой акт передачи данных выглядит, как если бы некий клиент, которому эти данные нужны, запрашивал их у сервера, который может их предоставить 7Обратная ситуация, когда клиент хочет передать что-то серверу, сути дела не меняет: сервер предоставляет услугу клиенту, на этот раз – по приему данных.. Отношения между программами, которые связываются по сети друг с другом, почти всегда асимметричны: одной что-то надо, у другой это что-то есть. При установлении соединения и приложение (программа-клиент), и служба (программа-сервер) используют механизм сокетов, описанный в лекции 11, однако ведут себя по-разному.

Служба, запускаясь на сервере, создает сетевой сокет и прикрепляет его к определенному порту сервера с помощью системного вызова bind(). Затем она регистрируется в качестве обработчика запросов (listener), приходящих на этот порт. Служба ждет запросов, и когда они поступают, предпринимает какие-нибудь действия, например, считывает пришедшие данные и анализирует их в соответствии со своим протоколом, отсылает какие-то данные абоненту, пославшему запрос и т. п.

Приложение, запускаясь на клиенте, также создает сокет и присоединяется с его помощью к тому же порту на сервере, где запущена служба, используя системный вызов connect(). Затем оно, как и служба, посылает и получает данные. Разницы между обменом данными по сетевому сокету и по сокету в файловой системе нет. Очередность обмена данными определяется прикладным протоколом.

Как приложение узнает, к какому именно порту необходимо подключиться? За большинством прикладных протоколов закреплен постоянный номер порта. Постоянные номера портов и названия соответствующих протоколов хранятся в файле /etc/services:

[root@localhost root]# wc /etc/services
553 2794 19869 /etc/services
[root@localhost root]# egrep "^(ftp|http|smtp|ssh).*tcp" /etc/services
ftp 21/tcp # File Transfer [Control]
ssh 22/tcp # SSH Remote Login Protocol
smtp 25/tcp mail # Simple Mail Transfer Protocol
http 80/tcp www www-http # World Wide Web HTTP
Пример 14.6. Постоянные номера портов для некоторых протоколов

Этот файл – не догма, а руководство к действию: каждый может организовать, допустим, сервис HTTP по 25-му порту. Только как об этом узнают другие клиенты и что подумают почтовые программы, ожидая по этому порту встретить сервис SMTP (пересылка почты)? Вывести список установленных соединений, а также служб-обработчиков можно командой netstat:

[root@localhost root]# netstat -anA inet
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 192.168.102.125:22 192.168.102.1:33208 ESTABLISHED
udp 0 0 0.0.0.0:11 0.0.0.0:*
Пример 14.7. Просмотр установленных соединений и служб

Здесь видно, что на компьютере зарегистрировано два TCP-обработчика (на портах 111 и 22), один UDP-обработчик по 11-му порту (понятие Listener, то есть обработчик соединения для UDP не имеет смысла), а также установлено одно соединение с компьютера 192.168.102.1, исходящий порт 33208, к 22-му порту (это порт службы Secure Shell, предоставляющей удаленный терминальный доступ... видимо, Гуревич работает?). В более сложных случаях, когда номер порта заранее неизвестен, а известно только название и версия сервиса, используется служба portmap, которая раздает незанятые порты службам и сообщает приложениям, к какому из них надо обратиться. Порт 111 соответствует именно этой службе.

Аягоз Имансакипова
Аягоз Имансакипова
Здравствуйте, при успешном окончании курса, сертификат на сколько часов выдается?
Тимур Булатов
Тимур Булатов
Актуален ли курс в 2022м году?
Виктор Харченко
Виктор Харченко
Россия, Донецк