UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
52 #endif
53 } else
54 err_quit("unknown address family %d", ai->ai_family);
55 pr->sasend = ai->ai_addr; /* содержит адрес получателя */
56 pr->sarecv = Calloc(1, ai->ai_addrlen);
57 pr->salast = Calloc(1, ai->ai_addrlen);
58 pr->sabind = Calloc(1, ai->ai_addrlen);
59 pr->salen = ai->ai_addrlen;
60 traceloop();
61 exit(0);
62 }
2-9
proto
10-13
-m
19-37
38-58
host_serv
addrinfo
proto
Функция
traceloop
Листинг 28.15. Функция traceloop: основной цикл обработки
//traceroute/traceloop.c
1 #include "trace.h"
2 void
3 traceloop(void)
4 {
5 int seq, code, done;
6 double rtt;
7 struct rec *rec;
8 struct timeval tvrecv;
9 recvfd = Socket(pr->sasend->sa_family, SOCK_RAW, pr->icmpproto);
10 setuid(getuid()); /* права привилегированного пользователя больше
не нужны */
11 #ifdef IPV6
12 if (pr->sasend->sa_family == AF_INET6 && verbose == 0) {
13 struct icmp6_filter myfilt;
14 ICMP6_FILTER_SETBLOCKALL(&myfilt);
15 ICMP6_FILTER_SETPASS(ICMP6_TIME_EXCEEDED, &myfilt);
16 ICMP6_FILTER_SETPASS(ICMP6_DST_UNREACH, &myfilt);
17 setsockopt(recvfd, IPPROTO_IPV6, ICMP6_FILTER,
18 &myfilt, sizeof(myfilt));
19 }
20 #endif
21 sendfd = Socket(pr->sasend->sa_family, SOCK_DGRAM, 0);
22 pr->sabind->sa_family = pr->sasend->sa_family;
23 sport = (getpid() & 0xffff) | 0x8000; /* UDP-порт отправителя # */
24 sock_set_port(pr->sabind, pr->salen, htons(sport));
25 Bind(sendfd, pr->sabind, pr->salen);
26 sig_alrm(SIGALRM);
27 seq = 0;
28 done = 0;
29 for (ttl = 1; ttl <= max_ttl && done == 0; ttl++) {
30 Setsockopt(sendfd, pr->ttllevel, pr->ttloptname, &ttl, sizeof(int));
31 bzero(pr->salast, pr->salen);
32 printf("%2d ", ttl);
33 fflush(stdout);
34 for (probe = 0; probe < nprobes; probe++) {
35 rec = (struct rec*)sendbuf;
36 rec->rec_seq = ++seq;
37 rec->rec_ttl = ttl;
38 Gettimeofday(&rec->rec_tv, NULL);
39 sock_set_port(pr->sasend, pr->salen, htons(dport + seq));
40 Sendto(sendfd, sendbuf, datalen, 0, pr->sasend, pr->salen);
41 if ((code = (*pr->recv)(seq, &tvrecv)) == -3)
42 printf(" *"); /* тайм-аут, ответа нет */
43 else {
44 char str[NI_MAXHOST];
45 if (sock_cmp_addr(pr->sarecv, pr->salast, pr->salen) != 0) {
46 if (getnameinfo(pr->sarecv, pr->salen, str, sizeof(str),