UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Чтобы продемонстрировать использование этих параметров, мы создали UDP-клиент и UDP-сервер. Клиент представлен в листинге 27.5. Он принимает маршрут от отправителя в командной строке подобно TCP-клиенту IPv4, представленному в листинге 27.4. Сервер печатает маршрут полученного сообщения и обращает этот маршрут для отправки сообщения в обратном направлении.
Листинг 27.5. UDP-клиент, использующий маршрутизацию от отправителя
1 #include "unp.h" 2 int 3 main(int argc, char **argv) 4 { 5 int с, sockfd, len = 0; 6 u_char *ptr = NULL; 7 void *rth; 8 struct addrinfo *ai; 9 if (argc < 2)10 err_quit("usage: udpcli01 [ <hostname> ... ] <hostname>");11 if (argc > 2) {12 int i;13 len = Inet6_rth_space(IPV6_RTHDR_TYPE_0, argc-2);14 ptr = Malloc(len);15 Inet6_rth_init(ptr, len, IPV6_RTHDR_TYPE_0, argc-2);16 for (i = 1; i < argc-1; i++) {17 ai = Host_serv(argv[i], NULL, AF_INET6, 0);18 Inet6_rth_add(ptr,19 &((struct sockaddr_in6*)ai->ai_addr)->sin6_addr);20 }21 }22 ai = Host_serv(argv[argc-1], SERV_PORT_STR, AF_INET6, SOCK_DGRAM);23 sockfd = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);24 if (ptr) {25 Setsockopt(sockfd, IPPROTO_IPV6, IPV6_RTHDR, ptr, len);26 free(ptr);27 }28 dg_cli(stdin, sockfd, ai->ai_addr, ai->ai_addrlen); /* do it all */29 exit(0);30 }11-21inet6_rth_spacemallochost_servinet6_rth_add22-23host_serv24-27setsockoptptrdg_cliПрограмма UDP-сервера не изменилась по сравнению с предыдущими примерами. Сервер открывает сокет и вызывает функцию
dg_echodg_echoЛистинг 27.6. Функция dg_echo, печатающая маршрут
//ipopts/dgechoprintroute.c 1 #include "unp.h" 2 void 3 dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen) 4 { 5 int n; 6 char mesg[MAXLINE]; 7 int on; 8 char control[MAXLINE]; 9 struct msghdr msg;10 struct cmsghdr *cmsg;11 struct iovec iov[1];12 on = 1;13 Setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on));14 bzero(&msg, sizeof(msg));15 iov[0].iov_base = mesg;16 msg.msg_name = pcliaddr;17 msg.msg_iov = iov;18 msg.msg_iovlen = 1;19 msg.msg_control = control;20 for (;;) {21 msg.msg_namelen = clilen;22 msg.msg_controllen = sizeof(control);23 iov[0].iov_len = MAXLINE;24 n = Recvmsg(sockfd, &msg, 0);25 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;26 cmsg = CMSG_NXTHDR(&msg, cmsg)) {27 if (cmsg->cmsg_level == IPPROTO_IPV6 &&28 cmsg->cmsg_type == IPV6_RTHDR) {
