Чтение онлайн

ЖАНРЫ

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

127: close(socks[0]);

128: return childProcess(argv[1], socks[1]);

129: }

130:

131: /* родительский процесс */

132: close(socks[1]);

133: parentProcess(socks[0]);

134:

135: /* закрытие дочернего процесса */

136: wait(&status);

137:

138: if (WEXITSTATUS(status))

139: fprintf(stderr, "childfailed\n");

140:

141: return 0;

142: }

17.5.

Сетевая обработка с помощью TCP/IP

Самое важное применение сокетов заключается в том, что они позволяют приложениям, работающим на основе различных механизмов, общаться друг с другом. Семейство протоколов TCP/IP [34] используется в Internet самым большим в мире числом компьютеров, объединенных в сеть. Система Linux предлагает полную устойчивую реализацию TCP/IP, которая позволяет действовать и как сервер, и как клиент TCP/IP.

Наиболее распространенной версией TCP/IP является версия 4 (IPv4). В данный момент для большинства операционных систем и продуктов сетевой инфраструктуры уже доступна версия 6 протокола TCP/IP (IPv6), однако IPv4 доминирует до сих пор. В данном разделе мы сосредоточимся на создании приложений для IPv4, но обратим внимание на отличия для приложений IPv6, а также для тех программ, которые должны поддерживать обе версии.

17.5.1. Упорядочение байтов

Сети TCP/IP, как правило, являются неоднородными; они включают в себя широкий ряд механизмов и архитектур. Одно из основных отличий между архитектурами связано со способом хранения чисел.

Машинные числа составляются из последовательности байтов. Например, целые числа в С обычно представляются 4 байтами (32 битами). Существует довольно много способов хранения этих четырех байтов в памяти компьютера. Архитектуры с обратным порядком байтов сохраняют старший (наиболее значимый) байт в наименьшем аппаратном адресе, остальные следуют в порядке от более значимого к менее значимому. Механизмы с прямым порядком байтов хранят многобайтовые значения в абсолютно противоположном порядке: наименее значимый байт отправляется в наименьший адрес памяти. В других механизмах байты сохраняются в различных порядках.

Так как многобайтовые значения являются частью протокола TCP/IP, то разработчики протоколов позаботились о едином стандарте способа передачи многобайтовых значений через сеть [126] . TCP/IP требует использования обратного порядка байтов для передачи протокольной информации и рекомендует также применять его к данным приложений (хотя попытки зафиксировать формат потока данных приложений не предпринимались) [127] . Упорядочение, которое применяется для многобайтовых значений, передаваемых через сеть, известно как сетевой порядок байтов.

126

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

127

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

Для преобразования порядка байтов хоста в сетевой порядок байтов используются четыре функции.

#include <netinet/in.h>

unsigned int htonl(unsigned int hostlong);

unsigned short htons(unsigned short hostshort);

unsigned int ntohl(unsigned int netlong);

unsigned short ntohs(unsigned short netshort);

Несмотря на то что прототип каждой из этих функций принимает значение без знака, все они отлично работают и для значений со знаком.

Первые две функции

htonl
и
htons
преобразуют длинные и короткие числа соответственно из порядка байтов хоста в сетевой порядок байтов. Последние две
ntohl
и
ntohs
выполняют обратные преобразования длинных и коротких чисел (из сетевого порядка в порядок хоста).

Хотя мы использовали термин длинный в описаниях, на самом деле, это неправильно. Обе функции

htonl
и
ntohl
принимают 32-битные значения, а не те, которые относятся к типу
long
. В прототипах обеих функций предполагалось, что они обрабатывают значения
int
, поскольку все платформы Linux в настоящее время используют 32-битные целые числа.

17.5.2. Адресация IPv4

Соединения IPv4 представляют собой кортеж из 4-х элементов (локальный хост, локальный порт, удаленный хост, удаленный порт). До установки соединения необходимо определить каждую его часть. Элементы локальный хост и удаленный хост являются IPv4-адресами. IPv4-адреса — это 32-битные (4-байтовые) числа, уникальные для всей установленной сети. Как правило, они записываются в виде aaa.bbb.ccc.ddd, где каждый элемент адреса является десятичным представлением одного из байтов адреса машины. Первое слева число в адресе соответствует самому значимому байту в адресе. Такой формат для IPv4-адресов известен как десятичное представление с разделителями-точками.

В связи с тем, что большинство компьютеров вынуждено поддерживать работу нескольких параллельных TCP/IP приложений, IP-номер не обеспечивает уникальную идентификацию для соединения на одной машине. Номера портов — это 16-битные числа, которые позволяют однозначно распознавать одну из сторон соединения на данном хосте. Объединение IPv4-адреса и номера порта обеспечивает идентификацию стороны соединения где-либо в пределах одной сети TCP/IP (например, Internet является единой TCP/IP сетью). Две конечные точки соединения образуют полное TCP-соединение, таким образом, две пары, состоящие из IP-номера и номера порта, однозначно определяют TCP/IP соединение в сети.

Распределение номеров портов для различных протоколов производится на основе раздела стандартов Internet, известного как официальные номера портов, который утверждается Агентством по выделению имен и уникальных параметров протоколов Internet (Internet Assigned Numbers Authority, LANA) [128] . Общие протоколы Internet, такие как ftp, telnet и http, имеют свои номера портов. Большинство серверов предусматривают данные службы на присвоенных номерах, что позволяет их легко найти. Некоторые сервера запускаются на альтернативных номерах портов, как правило, для поддержки нескольких служб на одной машине [129] . Поскольку официальные номера портов не изменяются, система Linux просто находит соответствие между именами протоколов (обычно называемых службами) и номерами портов с помощью файла

/etc/services
.

128

Информация о IANA доступна по адресу http://www.iana.org.

129

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

Все номера портов попадают в диапазон от 0 до 65 535; в системе Linux они разделяются на два класса. Зарезервированные порты с номерами от 0 до 1 024 могут использоваться только процессами, работающими как root. Это позволяет клиентским программам иметь гарантию того, что программа, запущенная на сервере, не является троянским конем, активизированным каким-то пользователем [130] .

IPv4-адреса хранятся в структуре

struct sockaddr_in
, которая определяется следующим образом.

130

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

Поделиться с друзьями: