-->

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

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

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

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

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

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

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

11 struct sockaddr_un cliaddr;

12 /* прототипы функций */

13 int readable_conn(int);

14 int readable_listen(void);

15 int readable_v4(void);

16 int readable_v6(void);

Массив client

2-17
 Поскольку демон может обрабатывать любое количество клиентов, для сохранения информации о каждом клиенте используется массив структур
client
. Они аналогичны структурам данных, которые использовались в разделе 6.8. Кроме дескриптора для доменного сокета Unix, через который осуществляется связь с клиентом, сохраняется также семейство адресов клиентского UDP-сокета
AF_INET
или
AF_INET6
и номер порта, связанного с сокетом. Далее объявляются прототипы функций и глобальные переменные, совместно используемые этими функциями.

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

Листинг 28.24. Первая часть функции main: создание сокетов

//icmpd/icmpd.c

 1 #include "icmpd.h"

 2 int

 3 main(int argc, char **argv)

 4 {

 5  int i, sockfd;

 6  struct sockaddr_un sun;

 7  if (argc != 1)

 8   err_quit("usage: icmpd");

 9  maxi = -1; /* индекс массива client[] */

10  for (i = 0; i < FD_SETSIZE; i++)

11   client[i].connfd = -1; /* -1 означает свободный элемент */

12  FD_ZERO(&allset);

13  fd4 = Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

14  FD_SET(fd4, &allset);

15  maxfd = fd4;

16 #ifdef IPV6

17  fd6 = Socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);

18  FD_SET(fd6, &allset);

19  maxfd = max(maxfd, fd6);

20 #endif

21  listenfd = Socket(AF_UNIX, SOCK_STREAM, 0);

22  sun.sun_family = AF_LOCAL;

23  strcpy(sun.sun_path, ICMPD_PATH);

24  unlink(ICMPD_PATH);

25  Bind(listenfd, (SA*)&sun, sizeof(sun));

26  Listen(listenfd, LISTENQ);

27  FD_SET(listenfd, &allset);

28  maxfd = max(maxfd, listenfd);

Инициализация массива client

9-10
 Инициализируется массив
client
путем присваивания значения -1 элементу присоединенного сокета.

Создание сокетов

12-28
 Создаются три сокета: символьный сокет ICMPv4, символьный сокет ICMPv6 и потоковый доменный сокет Unix. Мы связываем при помощи функции
bind
свое заранее известное полное имя с сокетом и вызываем функцию
listen
. Это сокет, к которому клиенты присоединяются с помощью функции
connect
. Для функции
select
также вычисляется максимальный дескриптор, а для вызовов функции
accept
в памяти размещается структура адреса сокета.

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

main
. Она содержит бесконечный цикл, вызывающий функцию
select
в ожидании, когда будет готов к чтению какой-либо из дескрипторов демона.

Листинг 28.25. Вторая часть функции main: обработка готового к чтению дескриптора

//icmpd/icmpd.c

29  for (;;) {

30   rset = allset;

31   nready = Select(maxfd+1, &rset, NULL, NULL, NULL);

32   if (FD_ISSET(listenfd, &rset))

33    if (readable_listen() <= 0)

34     continue;

35   if (FD_ISSET(fd4, &rset))

36    if (readable_v4() <= 0)

37     continue;

38 #ifdef IPV6

39   if (FD_ISSET(fd6, &rset))

40    if (readable_v6() <= 0)

41     continue;

42 #endif

43   for (i = 0; i <= maxi; i++) { /* проверка всех клиентов */

44    if ( (sockfd = client[i].connfd) < 0)

45     continue;

46    if (FD_ISSET(sockfd, &rset))

47     if (readable_conn(i) <= 0)

48      break; /* готовых дескрипторов больше нет */

49   }

50  }

51  exit(0);

52 }

Проверка прослушиваемого доменного сокета Unix

32-34
 Прослушиваемый доменный сокет Unix проверяется в первую очередь, и если он готов, запускается функция
readable_listen
. Переменная
nready
— количество дескрипторов, которое функция select возвращает как готовые к чтению — является глобальной. Каждая из наших функций
readablе_XXX
уменьшает ее значение на 1, и новое значение этой переменной является возвращаемым значением функции. Когда ее значение достигает нуля, это говорит о том, что все готовые к чтению дескрипторы обработаны, и поэтому функция
select
вызывается снова.

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