UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
17-22waitpidstatusWEXITSTATUSopenfileerrno23read_fdПри отправке и получении дескриптора по потоковому каналу мы всегда отправляем как минимум 1 байт данных, даже если получатель никак эти данные не обрабатывает. Иначе получатель не сможет распознать, что значит нулевое возвращаемое значение из функции read_fd: отсутствие данных (но, возможно, есть дескриптор) или конец файла.
В листинге 15.9 показана функция
readfdrecvmsgreadrecvfdrecvfdЛистинг 15.9. Функция read_fd: получение данных и дескриптора
//lib/read_fd.c 1 #include "unp.h" 2 ssize_t 3 read_fd(int fd, void *ptr, size_t nbytes, int *recvfd) 4 { 5 struct msghdr msg; 6 struct iovec iov[1]; 7 ssize_t n; 8 int newfd; 9 #ifdef HAVE_MSGHDR_MSG_CONTROL10 union {11 struct cmsghdr cm;12 char control[CMSG_SPACE(sizeof(int))];13 } control_un;14 struct cmsghdr *cmptr;15 msg.msg_control = control_un.control;16 msg.msg_controllen = sizeof(control_un.control);17 #else18 msg.msg_accrights = (caddr_t)&newfd;19 msg.msg_accrightslen = sizeof(int);20 #endif21 msg.msg_name = NULL;22 msg.msg_namelen = 0;23 iov[0].iov_base = ptr;24 iov[0].iov_len = nbytes;25 msg.msg_iov = iov;26 msg.msg_iovlen = 1;27 if ((n = recvmsg(fd, &msg, 0)) <= 0)28 return (n);29 #ifdef HAVE_MSGHDR_MSG_CONTROL30 if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&31 mptr->cmsg_len == CMSG_LEN(sizeof(int))) {32 if (cmptr->cmsg_level != SOL_SOCKET)33 err_quit("control level != SOL_SOCKET");34 if (cmptr->cmsg_type != SCM_RIGHTS)35 err_quit("control type != SCM_RIGHTS");36 *recvfd = *((int*)CMSG_DATA(cmptr));37 } else38 *recvfd = -1; /* дескриптор не был передан */39 #else40 if (msg.msg_accrightslen == sizeof(int))41 *recvfd = newfd;42 else43 *recvfd = -1; /* дескриптор не был передан */44 #endif45 return (n);46 }8-26recvmsgmsg_controlmsg_accrightsconfig.hHAVE_MSGHDR_MSG_CONTROLrecvmsgmsg_control10-13msg_controlmsghdrcharcmsghdrmalloc27-45recvmsgrecvfdCMSG_DATAcmsg_dataunsigned charint
