UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
В листинге 21.2 представлена вторая часть функции
mcast_join
Листинг 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
ip_mreq
if_indextoname
ip_mreq
ioctl
39-46
ip_mreq
SIOCGIFADDR
ioctl
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;
60 } else if (ifname != NULL) {
61 if ((mreq6.ipv6mr_interface = if_nametoindex(ifname)) == 0) {
62 errno = ENXIO; /* интерфейс не найден */
63 return(-1);
64 }
65 } else
66 mreq6.ipv6mr_interface = 0;
67 return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
68 &mreq6, sizeof(mreq6)));
69 }
70 #endif
71 default:
72 errno = EAFNOSUPPORT;
73 return(-1);
74 }
75 #endif
76 }
55-57
ipv6_mreq
58-66
ipv6mr_interface
if_nametoindex
setsockopt
67-68
Пример: функция mcast_set_loop
В листинге 21.4 показана наша функция
mcast_set_loop
Поскольку аргументом является дескриптор сокета, а не структура адреса сокета, мы вызываем нашу функцию
sockfd_to_family
Мы не показываем исходный код для всех остальных функций
mcast_<i>XXX</i>
Листинг 21.4. Установка параметра закольцовки для многоадресной передачи
//lib/mcast_set_loop.c
1 #include "unp.h"
2 int
3 mcast_set_loop(int sockfd, int onoff)