-->

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

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

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

UNIX: разработка сетевых приложений - читать бесплатно онлайн , автор Стивенс Уильям Ричард

Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

Перейти на страницу:

31    goto clienterr;

32   }

33  }

34  Write(unixfd, "1", 1); /* сообщение клиенту об успехе */

35  Close(recvfd); /* работа с UDP-сокетом клиента завершена */

36  return(--nready);

37 clienterr:

38  Write(unixfd, "0", 1); /* сообщение клиенту об ошибке */

39 clientdone:

40  Close(unixfd);

41  if (recvfd >= 0)

42   Close(recvfd);

43  FD_CLR(unixfd, &allset);

44  client[i].connfd = -1;

45  return(--nready);

46 }

Получение номера порта, связанного с сокетом UDP

21-25
 Вызывается функция
getsockname
, так что демон может получить номер порта, связанного с сокетом. Поскольку неизвестно, каков размер буфера, необходимого для размещения структуры адреса сокета, мы используем структуру
sockaddr_storage
, которая достаточно велика для структуры адреса сокета любого поддерживаемого системой типа и обеспечивает нужное выравнивание.

26-33
 Семейство адресов сокета вместе с номером порта сохраняется в структуре
client
. Если номер порта равен нулю, мы вызываем функцию
sock_bind_wild
для связывания универсального адреса и динамически назначаемого порта с сокетом, но, как отмечалось ранее, такой подход не работает в реализациях SVR4.

Сообщение клиенту об успехе

34
 Один байт, содержащий символ
"1"
, отправляется обратно клиенту.

Закрытие UDP-сокета клиента

35
 Заканчиваем работу с UDP-сокетом клиента и закрываем его с помощью функции
close
. Дескриптор был переслан нам клиентом и, таким образом, является копией; следовательно, UDP-сокет все еще открыт на стороне клиента.

Обработка ошибок и завершение работы клиента

37-45
 Если происходит ошибка, клиент получает нулевой байт. Когда клиент завершается, наша часть доменного сокета Unix закрывается, и соответствующий дескриптор удаляется из набора дескрипторов для функции
select
. Полю
connfd
структуры
client
присваивается значение -1, что является указанием на ее освобождение.

Функция

readable_v4
вызывается, когда символьный сокет ICMPv4 открыт для чтения. Первая часть данной функции приведена в листинге 28.29. Этот код аналогичен коду для ICMPv4, приведенному ранее в листингах 28.6 и 28.15.

Листинг 28.29. Обработка полученных дейтаграмм ICMPv4, первая часть

//icmpd/readable_v4.c

 1 #include "icmpd.h"

 2 #include <netinet/in_systm.h>

 3 #include <netinet/ip.h>

 4 #include <netinet/ip_icmp.h>

 5 #include <netinet/udp.h>

 6 int

 7 readable_v4(void)

 8 {

 9  int i, hlen1, hlen2, icmplen, sport;

10  char buf[MAXLINE];

11  char srcstr[INET_ADDRSTRLEN], dststr[INET_ADDRSTRLEN];

12  ssize_t n;

13  socklen_t len;

14  struct ip *ip, *hip;

15  struct icmp *icmp;

16  struct udphdr *udp;

17  struct sockaddr_in from, dest;

18  struct icmpd_err icmpd_err;

19  len = sizeof(from);

20  n = Recvfrom(fd4, buf, MAXLINE, 0, (SA*)&from, &len);

21  printf("%d bytes ICMPv4 from %s:", n, Sock_ntop_host((SA*)&from, len));

22  ip = (struct ip*)buf; /* начало IP-заголовка */

23  hlen1 = ip->ip_hl << 2; /* длина IP-заголовка */

24  icmp = (struct icmp*)(buf + hlen1); /* начало ICMP-заголовка */

25  if ((icmplen = n - hlen1) < 8)

26   err_quit("icmplen (%d) < 8", icmplen);

27  printf(" type = %d, code = %dn", icmp->icmp_type, icmp->icmp_code);

Функция выводит некоторую информацию о каждом получаемом сообщении ICMP. Это было сделано для отладки при разработке демона, и вывод управляется аргументом командной строки.

В листинге 28.30 приведена вторая часть функции

readable_v4
.

Листинг 28.30. Обработка полученных дейтаграмм ICMPv4, вторая часть

//icmpd/readable_v4.c

28  if (icmp->icmp_type == ICMP_UNREACH ||

29   icmp->icmp_type ==ICMP_TIMXCEED ||

30   icmp->icmp_type == ICMP_SOURCEQUENCH) {

31   if (icmplen < 8 + 20 + 8)

32    err_quit("icmplen (%d) < 8 + 20 + 8, icmplen);

33   hip = (struct ip*)(buf + hlen1 + 8);

34   hlen2 = hip->ip_hl << 2;

35   printf("tsrcip = %s, dstip = %s, proto = %dn",

36    Inet_ntop(AF_INET, &hip->ip_src, srcstr, sizeof(srcstr)),

37    Inet_ntop(AF_INET, &hip->ip_dst, dststr, sizeof(dststr)),

38    hip->ip_p);

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