UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
1 #include "unp.h" 2 #include <sys/param.h> /* макрос ALIGN для макроса CMSG_NXTHDR() */ 3 ssize_t 4 recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp, 5 SA *sa, socklen_t *salenptr, struct unp_in_pktinfo *pktp) 6 { 7 struct msghdr msg; 8 struct iovec iov[1]; 9 ssize_t n;10 #ifdef HAVE_MSGHDR_MSG_CONTROL11 struct cmsghdr *cmptr;12 union {13 struct cmsghdr cm;14 char control[CMSG_SPACE(sizeof(struct in_addr)) +15 CMSG_SPACE(sizeof(struct unp_in_pktinfo))];16 } control_un;17 msg.msg_control = control_un.control;18 msg.msg_controllen = sizeof(control_un.control);19 msg.msg_flags = 0;20 #else21 bzero(&msg, sizeof(msg)); /* обнуление msg_accrightslen = 0 */22 #endif23 msg.msg_name = sa;24 msg.msg_namelen = *salenptr;25 iov[0].iov_base = ptr;26 iov[0].iov_len = nbytes;27 msg.msg_iov = iov;28 msg.msg_iovlen = 1;29 if ((n = recvmsg(fd, &msg, *flagsp)) < 0)30 return(n);31 *salenptr = msg.msg_namelen; /* возвращение результатов */32 if (pktp)33 bzero(pktp, sizeof(struct unp_in_pktinfo)); /* 0.0.0.0. интерфейс = 0 */1-2CMSG_NXTHDR<sys/param.h>3-5recvfromrecvmsgunp_in_pktinfo10-22msghdrMSG_<i>XXX</i>#ifdefmsg_controlIP_RECVDSTADDRIP_RECVIF23-33msghdrrecvmsgmsg_namelenmsg_flagsunp_in_pktinfoВ листинге 22.2 показана вторая часть нашей функции.
Листинг 22.2. Функция recvfrom_flags: возвращаемые флаги и адрес получателя
//advio/recvfromflags.c34 #ifndef HAVE_MSGHDR_MSG_CONTROL35 *flagsp = 0; /* возвращение результатов */36 return(n);37 #else38 *flagsp = msg.msg_flags; /* возвращение результатов */39 if (msg.msg_controllen < sizeof(struct cmsghdr) ||40 (msg.msg_flags & MSG_CTRUNC) || pktp == NULL)41 return(n);42 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;43 cmptr = CMSG_NXTHDR(&msg, cmptr)) {44 #ifdef IP_RECVDSTADDR45 if (cmptr->cmsg_level == IPPROTO_IP &&46 cmptr->cmsg_type == IP_RECVDSTADDR) {47 memcpy(&pktp->ipi_addr, CMSG_DATA(cmptr),48 sizeof(struct in_addr));49 continue;50 }51 #endif52 #ifdef IP_RECVIF53 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF) {54 struct sockaddr_dl *sdl;55 sdl = (struct sockaddr_dl*)CMSG_DATA(cmptr);56 pktp->ipi_ifindex = sdl->sdl_index;57 continue;58 }59 #endif60 err_quit("unknown ancillary data, len = %d, level = %d, type = %d",
