KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программное обеспечение » Уильям Стивенс - UNIX: разработка сетевых приложений

Уильям Стивенс - UNIX: разработка сетевых приложений

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Уильям Стивенс, "UNIX: разработка сетевых приложений" бесплатно, без регистрации.
Перейти на страницу:

Если локальный интерфейс задается как универсальный адрес (INADDR_ANY для IPv4) или как нулевой индекс IPv6, то конкретный локальный интерфейс выбирается ядром.

■ IP_ADD_SOURCE_MEMBERSHIР, MCAST_JOIN_SOURCE_GROUP. Присоединение к группе конкретного источника на заданном локальном интерфейсе. С этим параметром используются те же структуры, что и с параметрами блокирования и разблокирования источника. Сокет не должен быть присоединен к той же группе без указания источника (параметры IP_ADD_MEMBERSHIP, IPV6_JOIN_GROUP, MCAST_JOIN_GROUP).

Если локальный интерфейс задается как универсальный адрес (INADDR_ANY для IPv4) или как нулевой индекс IPv6, то конкретный локальный интерфейс выбирается ядром.

■ IP_DROP_SOURCE_MEMBERSHIP, MCAST_LEAVE_SOURCE_GROUP. Отключение от группы источника конкретного локального интерфейса. Используются те же структуры, что и с предыдущими параметрами сокетов. Если локальный интерфейс не указан (значение INADDR_ANY для IPv4 или 0 для независимого от версии API), отключается первая группа, удовлетворяющая заданным значениям.

Если процесс присоединяется к группе источника, но не отключается от нее явно, отсоединение производится автоматически при закрытии сокета (явном или также автоматическом, при завершении процесса). Несколько процессов узла могут присоединиться к одной и той же группе источника, в случае чего узел остается в группе до тех пор, пока из нее не выйдет последний процесс.

■ IP_MULTICAST_IF и IPV6_MULTICAST_IF. Назначение этих параметров - задание интерфейса для исходящих дейтаграмм многоадресной передачи, отправленных на этом сокете. Этот интерфейс задается либо структурой in_addr для IPv4, либо индексом интерфейса для IPv6. Если задано значение INADDR_ANY для IPv4 или нулевой индекс интерфейса для IPv6, то удаляется любой интерфейс, ранее заданный этим параметром сокета, и система будет выбирать интерфейс каждый раз при отправке дейтаграммы.

Будьте внимательны, четко различая локальный интерфейс, заданный (или выбранный), когда процесс присоединяется к группе (интерфейс для получения приходящих дейтаграмм многоадресной передачи), и локальный интерфейс, заданный (или выбранный) для исходящих дейтаграмм.

ПРИМЕЧАНИЕ

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

■ IP_MULTICAST_TTL и IPV6_MULTICAST_HOPS. Назначение этих параметров - установка значения поля TTL в случае IPv4 или предельного количества транзитных узлов в случае IPv6 для исходящих дейтаграмм многоадресной передачи. По умолчанию значение обоих параметров равно 1, что ограничивает дейтаграмму локальной подсетью.

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

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

ПРИМЕЧАНИЕ

Описываемая здесь закольцовка является внутренней и выполняется на уровне IP или выше. Если интерфейс получает копии своих передач, RFC 1112 [26] требует, чтобы драйвер игнорировал эти копии. В этом документе также утверждается, что параметр закольцовки по умолчанию включен «в целях оптимизации производительности для протоколов верхнего уровня, которые ограничивают членство в группе до одного процесса на узел (например, маршрутизирующих протоколов)».

Первые шесть пар параметров сокетов (ADD_MEMBERSHIP/JOIN_GROUP, DROP_MEMBERSHIP/LEAVE_GROUP, BLOCK_SOURCE, UNBLOCK_SOURCE, ADD_SOURCE_MEMBERSHIP/JOIN_SOURCE_GROUP, DROP_SOURCE_MEMBERSHIP/LEAVE_SOURCE_GROUP) влияют на получение дейтаграмм многоадресной передачи, в то время как последние три пары параметров влияют на отправку дейтаграмм многоадресной передачи (интерфейс для исходящих сообщений, TTL или предел количества транзитных узлов, закольцовка). Ранее мы отмечали, что для отправки дейтаграммы многоадресной передачи ничего особенного не требуется. Если ни один параметр сокетов многоадресной передачи не задан перед отправкой дейтаграммы, интерфейс для исходящей дейтаграммы будет выбран ядром, TTL или предел количества транзитных узлов будут равны 1, а копия отправленной дейтаграммы будет посылаться обратно (то есть будет включена закольцовка).

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

ПРИМЕЧАНИЕ

Исторически Беркли-реализации требуют только, чтобы некоторый сокет на узле присоединился к группе — это не обязательно тот сокет, который связывается с портом и затем получает дейтаграммы многоадресной передачи. Однако есть вероятность, что эти реализации могут доставлять дейтаграммы многоадресной передачи приложениям, не знающим о многоадресной передаче. Более новые ядра требуют, чтобы процесс связывался с портом и устанавливал какой-нибудь параметр сокета многоадресной передачи для сокета как указатель того, что приложение знает о многоадресной передаче. Самый обычный параметр сокета многоадресной передачи — признак присоединения к группе. Для Solaris 2.5 характерны некоторые отличия: дейтаграммы многоадресной передачи доставляются только на те сокеты, которые присоединились к группе и связались с портом. В целях переносимости все приложения многоадресной передачи должны присоединиться к группе и связаться с портом.

Более новый интерфейс многоадресного сервиса требует, чтобы уровень IP доставлял многоадресные пакеты сокету только в том случае, если этот сокет присоединился к группе или источнику. Такое требование было введено с IGMPv3 (RFC 3376 [16]), чтобы разрешить фильтрацию источников и многоадресную передачу от источника. Таким образом ужесточается требование на присоединение к группе, но зато ослабляется требование на связывание группового адреса. Однако для наибольшей переносимости со старыми и новыми интерфейсами приложения должны присоединяться к группам и связывать сокеты с групповыми адресами.

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

21.7. Функция mcast_join и родственные функции

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

#include "unp.h"


int mcast_join(int sockfd, const struct sockaddr *grp,

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*