Читать «UNIX: разработка сетевых приложений» онлайн - страница 55
Уильям Ричард Стивенс
Часть 2
Элементарные сокеты
Глава 3
Введение в сокеты
3.1. Введение
Эта глава начинается с описания программного интерфейса приложения (API) сокетов. Мы начнем со структур адресов сокетов, которые будут встречаться почти в каждом примере на протяжении всей книги. Эти структуры можно передавать в двух направлениях: от процесса к ядру и от ядра к процессу. Последний случай — пример аргумента, через который передается возвращаемое значение, и далее в книге мы встретимся с другими примерами таких аргументов.
Перевод текстового представления адреса в двоичное значение, входящее в структуру адреса сокета, осуществляется функциями преобразования адресов. В большей части существующего кода IPv4 используются функции inet_addr
и inet_ntoa
, но две новых функции inet_pton
и inet_ntop
работают и с IPv4, и с IPv6.
Одной из проблем этих функций является то, что они зависят от протокола, так как для них имеет значение тип преобразуемого адреса — IPv4 или IPv6. Мы разработали набор функций, названия которых начинаются с sock_
, работающих со структурами адресов сокетов независимо от протокола. Эти функции мы и будем использовать, чтобы сделать наш код не зависящим от протокола.
3.2. Структуры адреса сокетов
Большинство функций сокетов используют в качестве аргумента указатель на структуру адреса сокета. Каждый набор протоколов определяет свою собственную структуру адреса сокетов. Имена этих структур начинаются с sockaddr_
и заканчиваются уникальным суффиксом для каждого набора протоколов.
Структура адреса сокета IPv4
Структура адреса сокета IPv4, обычно называемая структурой адреса сокета Интернета, именуется sockaddr_in
и определяется в заголовочном файле <netinet/in.h>
. В листинге 3.1 представлено определение POSIX.
Листинг 3.1. Структура адреса сокета Интернета (IPv4): sockaddr_in
struct in_addr {
in_addr_t s_addr; /* 32-разрядный адрес IPv4 */
/* сетевой порядок байтов */
};
struct sockaddr_in {
uint8_t sin_len; /* длина структуры (16) */
sa_family_t sin_family; /* AF_INET */
in_port_t sin_port; /* 16-разрядный номер порта TCP или UDP */
/* сетевой порядок байтов */
struct in_addr sin_addr; /* 32-разрядный адрес IPv4 */
/* сетевой порядок байтов */
char sin_zero[8]; /* не используется */
};
Есть несколько моментов, касающихся структур адреса сокета в целом, которые мы покажем на примере.
■ Элемент длины sin_len
появился в версии 4.3BSD-Reno, когда была добавлена поддержка протоколов OSI (см. рис. 1.6). До этой реализации первым элементом был sin_family
, который исторически имел тип unsigned short
(целое без знака). Не все производители поддерживают поле длины для структур адреса сокета, и в POSIX, например, не требуется наличия этого элемента. Типы данных, подобные uint8_t
, введены в POSIX (см. табл. 3.1). Наличие поля длины упрощает обработку структур адреса сокета с переменной длиной.