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-21
inet6_rth_space
malloc
host_serv
inet6_rth_add
22-23
host_serv
24-27
setsockopt
ptr
dg_cli
Программа UDP-сервера не изменилась по сравнению с предыдущими примерами. Сервер открывает сокет и вызывает функцию
dg_echo
dg_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) {