UNIX: разработка сетевых приложений

На нашем литературном портале можно бесплатно читать книгу UNIX: разработка сетевых приложений, Стивенс Уильям Ричард-- . Жанр: ОС и Сети. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
UNIX: разработка сетевых приложений
Название: UNIX: разработка сетевых приложений
Дата добавления: 16 январь 2020
Количество просмотров: 393
Читать онлайн

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 }

Определение структуры proto

2-9
 Определяются две структуры
proto
, одна для IPv4 и другая для IPv6, хотя указатели на структуры адреса сокета не размещаются в памяти до окончания выполнения данной функции.

Установка значений по умолчанию

10-13
 Максимальное значение поля TTL или поля предельного количества транзитных узлов, используемое в программе, по умолчанию равно 30. Предусмотрен параметр командной строки
-m
, чтобы пользователь мог поменять это значение. Для каждого значения TTL посылается три пробных пакета, но их количество также может быть изменено с помощью параметра командной строки. Изначально используется номер порта получателя 32 768 + 666, и каждый раз, когда посылается новая дейтаграмма UDP, это значение увеличивается на 1. Мы можем надеяться, что порты с такими номерами не используются на узле получателя в тот момент, когда приходит дейтаграмма, однако гарантии здесь нет.

Обработка аргументов командной строки

19-37
 Параметр командной строки -v позволяет вывести все остальные ICMP-сообщения.

Обработка имени узла или IP-адреса и завершение инициализации

38-58
 Имя узла получателя или IP-адрес обрабатывается функцией
host_serv
, возвращающей указатель на структуру
addrinfo
. В зависимости от типа возвращенного адреса (IPv4 или IPv6) заканчивается инициализация структуры
proto
, сохраняется указатель в глобальной переменной pr, а также размещается в памяти дополнительная структура адреса сокета соответствующего размера.

Функция

traceloop
, приведенная в листинге 28.15, отправляет дейтаграммы и читает вернувшиеся ICMP-сообщения. Это основной цикл программы.

Листинг 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),

Перейти на страницу:
Комментариев (0)
название