Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

23-24
Присоединение к группе выполняется вызовом
setsockopt
. Аргумент
level
определяется на основании семейства группового адреса вызовом нашей собственной функции
family_to_level
. Некоторые системы допускают несоответствие аргумента level семейству адреса сокета, например использование
IPPROTO_IP
с
MCAST_JOIN_GROUP
, даже если сокет относится к семейству
AF_INET6
, но это верно не для всех систем, поэтому мы и должны выполнить преобразование семейства к нужному значению
level
. Листинг этой тривиальной функции в книге мы не приводим, но исходный код этой функции вы можете скачать вместе со всеми остальными программами.

В листинге 21.2 представлена вторая часть функции

mcast_join
, обрабатывающая сокеты IPv4.

Листинг 21.2. Присоединение к группе: обработка сокета IPv4

26 switch (grp->sa_family) {

27 case AF_INET: {

28 struct ip_mreq mreq;

29 struct ifreq ifreq;

30 memcpy(&mreq.imr_multiaddr,

31 &((const struct sockaddr_in*)grp)->sin_addr,

32 sizeof(struct in_addr));

33 if (ifindex > 0) {

34 if (if_indextoname(ifindex, ifreq.ifr_name) == NULL) {

35 errno = ENXIO; /* i/f index not found */

36 return(-1);

37 }

38 goto doioctl;

39 } else if (ifname != NULL) {

40 strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);

41 doioctl:

42 if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0)

43 return(-1);

44 memcpy(&mreq.imr_interface,

45 &((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr,

46 sizeof(struct in_addr));

47 } else

48 mreq.imr_interface.s_addr = htonl(INADDR_ANY);

49 return(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,

50 &mreq, sizeof(mreq)));

51 }

Обработка индекса

33-38
Адрес многоадресной передачи IPv4 в структуре адреса сокета копируется в структуру
ip_mreq
. Если индекс был задан, вызывается функция
if_indextoname
, сохраняющая имя в нашей структуре
ip_mreq
. Если это выполняется успешно, мы переходим на точку вызова
ioctl
.

Обработка имени

39-46
Имя вызывающего процесса копируется в структуру
ip_mreq
, а вызов
SIOCGIFADDR
функции
ioctl
возвращает адрес многоадресной передачи, связанный с этим именем. При успешном выполнении адрес IPv4 копируется в элемент
imr_interface
структуры
ip_mreq
.

Значения по умолчанию

47-48
Если ни индекс, ни имя не заданы, используется универсальный адрес, что указывает ядру на необходимость выбрать интерфейс.

49-50
Функция
setsockopt
выполняет присоединение к группе.

Третья, и последняя, часть функции, обрабатывающая сокеты IPv6, приведена в листинге 21.3.

Листинг 21.3. Присоединение к группе: обработка сокета IPv6

52 #ifdef IPV6

53 case AF_INET6: {

54 struct ipv6_mreq mreq6;

55 memcpy(&mreq6.ipv6mr_multiaddr,

56 &((const struct sockaddr_in6*) grp)->sin6_addr,

57 sizeof(struct in6_addr));

58 if (ifindex > 0) {

59 mreq6.ipv6mr_interface = ifindex;

  • Читать дальше
  • 1
  • ...
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: