Читать «UNIX: разработка сетевых приложений» онлайн - страница 60
Уильям Ричард Стивенс
/* зависящие от реализации элементы, обеспечивающие:
а) выравнивание, достаточное для выполнения требований по выравниванию всех
типов адресов сокетов, поддерживаемых системой;
б) достаточный объем для хранения адреса сокета любого типа,
поддерживаемого системой. */
};
Тип sockaddr_storage
— это универсальная структура адреса сокета, отличающаяся от struct sockaddr
по следующим параметрам:
1. Если к структурам адресов сокетов, поддерживаемым системой, предъявляются требования по выравниванию, структура sockaddr_storage
выполняет самое жесткое из них.
2. Структура sockaddr_storage
достаточно велика для размещения любой структуры адреса сокета, поддерживаемой системой.
Заметьте, что поля структуры sockaddr_storage
непрозрачны для пользователя, за исключением ss_family
и ss_len
(если таковые заданы). Структура sockaddr_storage
должна преобразовываться в структуру адреса соответствующего типа для обращения к содержимому остальных полей.
Сравнение структур адреса сокетов
На рис. 3.1 показано сравнение пяти структур адресов сокетов, с которыми мы встретимся в тексте, предназначенных для IPv4, IPv6, доменного сокета Unix (см. листинг 15.1), канального уровня (см. листинг 18.1) и хранения. Подразумевается, что все структуры адреса сокета содержат 1-байтовое поле длины, поле семейства также занимает 1 байт и длина любого поля, размер которого ограничен снизу, в точности равна этому ограничению.
Рис. 3.1. Сравнение различных структур адресов сокетов
Две структуры адреса сокета имеют фиксированную длину, а структура доменного сокета Unix и структура канального уровня — переменную. При обработке структур переменной длины мы передаем функциям сокетов указатель на структуру адреса сокета, а в другом аргументе передаем длину этой структуры. Под каждой структурой фиксированной длины мы показываем ее размер в байтах (для реализации 4.4BSD).
ПРИМЕЧАНИЕ
Сама структура sockaddr_un имеет фиксированную длину, но объем информации в ней — длина полного имени (pathname) — может быть переменным. Передавая указатели на эти структуры, следует соблюдать аккуратность при обработке поля длины — как длины в структуре адреса сокета (если поле длины поддерживается данной реализацией), так и длины данных, передаваемых ядру и принимаемых от него.
Этот рисунок служит также иллюстрацией стиля, которого мы придерживаемся в этой книге: названия структур на рисунках всегда выделяются полужирным шрифтом, а за ними следуют фигурные скобки.
Ранее отмечалось, что в реализации 4.3BSD Reno ко всем структурам адресов сокетов было добавлено поле длины. Если бы поле длины присутствовало в оригинальной реализации сокетов, то не возникло бы необходимости передавать аргумент длины функциям сокетов (третий аргумент функций bind и connect). Вместо этого размер структуры мог бы храниться в поле длины структуры.
3.3. Аргументы типа «значение-результат»
Мы отмечали, что когда структура адреса сокета передается какой-либо из функций сокетов, она всегда передается по ссылке, то есть в качестве аргумента передается указатель на структуру. Длина структуры также передается в качестве аргумента. Но способ, которым передается длина, зависит от того, в каком направлении передается структура: от процесса к ядру или наоборот.