UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Параметры IPv4 TTL и закольцовки получают аргумент типа u_char, в то время как IPv6-параметры предела транзитных узлов и закольцовки получают аргументы соответственно типа int и u_int. Распространенная ошибка программирования с параметрами многоадресной передачи IPv4 — вызов функции setsockopt с аргументом типа int для задания TTL или закольцовки (что не разрешается [128, с. 354–355]), поскольку большинство других параметров сокетов, представленных в табл. 7.1, имеют целочисленные аргументы. Изменения, внесенные в IPv6, должны уменьшить вероятность ошибок.
Теперь мы опишем каждый из девяти параметров сокетов более подробно. Обратите внимание, что эти девять параметров концептуально идентичны в IPv4 и IPv6 — различаются только их названия и типы аргументов.
■
IP_ADD_MEMBERSHIP
IPV6_JOIN_GROUP
MCAST_JOIN_GROUP
struct ip_mreq {
struct in_addr imr_multiaddr; /* IPv4-адрес многоадресной
передачи класса D */
struct in_addr imr_interface; /* IPv4-адрес локального
интерфейса */
};
struct ipv6_mreq {
struct in6_addr ipv6mr_multiaddr; /* IPv6-адрес многоадресной
передачи */
unsigned int ipv6mr_interface; /* индекс интерфейса или 0 */
};
struct group_req {
unsigned int gr_interface; /* индекс интерфейса или 0 */
struct sockaddr_storage gr_group; /* адрес многоадресной передачи
IPv4 или IPv6 */
};
Если локальный интерфейс задается как универсальный адрес (
INADDR_ANY
Мы говорим, что узел принадлежит к данной группе на данном интерфейсе, если один или более процессов в настоящий момент принадлежат к этой группе на этом интерфейсе.
Сокет может быть присоединен к нескольким группам, но к каждой группе должен быть присоединен уникальный адрес или уникальный интерфейс. Это свойство можно использовать на узле с несколькими сетевыми интерфейсами: создается один сокет, которому присваивается один адрес многоадресной передачи, но благодаря наличию разных интерфейсов этот сокет может быть присоединен к разным группам.
Вспомните из табл. 21.1, что частью адреса многоадресной передачи IPv6 является поле области действия. Как мы отмечали, адреса многоадресной передачи IPv6, отличающиеся только областью действия, являются различными. Следовательно, если реализация протокола синхронизации времени (network time protocol, NTP) хочет получать все пакеты NTP независимо от их области действия, она должна будет присоединиться к адресу
ff01:101
ff02:101
ff05:101
ff08:101
ff0e:101
IPV6_PKTINFO
Независимый от версии IP параметр сокета (
MCAST_JOIN_GROUP
sockaddr_storage
in6_addr
sockaddr_storage
В большинстве реализаций число присоединений, допустимых для одного сокета, ограничено. Предел определяется константой IP_MAX_MEMBERSHIPS (для Беркли-реализаций ее значение равно 20). В некоторых реализациях это ограничение снято, в других оно значительно превышает значение для Беркли-реализаций.
Когда интерфейс, на котором будет происходить присоединение, не задан, Беркли-ядра ищут адрес многоадресной передачи в обычной таблице маршрутизации IP и используют полученный в результате интерфейс [128, с. 357]. Некоторые системы для обработки этой ситуации устанавливают маршрут для всех адресов многоадресной передачи (то есть маршрут с адресом получателя 224.0.0.0/8 для IPv4) в процессе инициализации.
Для IPv6 сделано изменение — при задании интерфейса используется индекс, а не локальный адрес направленной передачи, как было в IPv4. Это позволяет выполнять присоединение на ненумерованных интерфейсах и конечных точках туннелей.
Изначально в API многоадресной передачи IPv6 использовалась константа IPV6_ADD_MEMBERSHIP, а не IPV6_JOIN_GROUP. Во всех остальных отношениях интерфейс программирования не изменился. Описанная далее функция mcast_join скрывает это отличие.
■
IP_DROP_MEMBERSHIP
IPV6_LEAVE_GROUP
MCAST_LEAVE_GROUP
INADDR_ANY
Если процесс присоединился к группе, но не выходил из группы явно, то при закрытии сокета (либо явном, либо по завершении процесса) вхождение в группу прекращается автоматически. Возможна ситуация, когда несколько процессов на узле присоединились к одной и той же группе, и в этом случае узел остается членом группы, пока последний процесс не выйдет из группы.
Изначально в API многоадресной передачи IPv6 использовалась константа IPV6_DROP_MEMBERSHIP, а не IPV6_LEAVE_GROUP. Во всех остальных отношениях интерфейс программирования не изменился. Описанная далее функция mcast_leave скрывает это отличие.
■
IP_BLOCK_SOURCE
MCAST_BLOCK_SOURCE