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

12 static long cntread[QSIZE +1]; /* диагностический счетчик */

13 static int iget; /* следующий элемент для обработки в основном цикле */

14 static int iput; /* следующий элемент для считывания обработчиком

                       сигналов */

15 static int nqueue; /* количество дейтаграмм в очереди на обработку

                         в основном цикле */

16 static socklen_t clilen; /* максимальная длина sockaddr{} */

17 static void sig_io(int);

18 static void sig_hup(int);

Очередь принимаемых дейтаграмм

3-12 Обработчик сигнала SIGIO помещает приходящие дейтаграммы в очередь. Эта очередь является массивом структур DG, который интерпретируется как кольцевой буфер. Каждая структура содержит указатель на принятую дейтаграмму, ее длину и указатель на структуру адреса сокета, содержащую адрес протокола клиента и размер адреса протокола. В памяти размещается столько этих структур, сколько указано в QSIZE (в данном случае 8), и в листинге 25.2 будет видно, что функция dg_echo для размещения в памяти всех структур дейтаграмм и адресов сокетов вызывает функцию malloc. Также происходит выделение памяти под диагностический счетчик cntread, который будет рассмотрен чуть ниже. На рис. 25.2 приведен массив структур, при этом предполагается, что первый элемент указывает на 150-байтовую дейтаграмму, а длина связанного с ней адреса сокета равна 16.

Рис. 25.2. Структуры данных, используемые для хранения прибывающих дейтаграмм и структур адресов их сокетов

Индексы массивов

13-15 Переменная iget является индексом следующего элемента массива для обработки в основном цикле, а переменная iput — это индекс следующего элемента массива, в котором сохраняется результат действия обработчика сигнала. Переменная nqueue обозначает полное количество дейтаграмм, предназначенных для обработки в основном цикле.

В листинге 25.2 показан основной цикл сервера — функция dg_echo.

Листинг 25.2. Функция dg_echo: основной обрабатывающий цикл сервера

//sigio/dgecho01.c

19 void

20 dg_echo(int sockfd_arg, SA *pcliaddr, socklen_t clilen_arg)

21 {

22  int i;

23  const int on = 1;

24  sigset_t zeromask, newmask, oldmask;

25  sockfd = sockfd_arg;

26  clilen = clilen_arg;

27  for (i = 0; i < QSIZE; i++) { /* инициализация очереди */

28   dg[i].dg_data = Malloc(MAXDG);

29   dg[i].dg_sa = Malloc(clilen);

30   dg[i].dg_salen = clilen;

31  }

32  iget = iput = nqueue = 0;

33  Signal(SIGHUP, sig_hup);

34  Signal(SIGIO, sig_io);

35  Fcntl(sockfd, F_SETOWN, getpid());

36  Ioctl(sockfd, FIOASYNC, &on);

37  Ioctl(sockfd. FIONBIO, &on);

38  Sigemptyset(&zeromask); /* инициализация трех наборов сигналов */

39  Sigemptyset(&oldmask);

40  Sigemptyset(&newmask);

41  Sigaddset(&newmask, SIGIO); /* сигнал, который хотим блокировать*/

42  Sigprocmask(SIG_BLOCK, &newmask, &oldmask);

43  for (;;) {

44   while (nqueue == 0)

45    sigsuspend(&zeromask); /* ждем дейтаграмму для обработки */

46   /* разблокирование SIGIO */

47   Sigprocmask(SIG_SETMASK, &oldmask, NULL);

48   Sendto(sockfd, dg[iget].dg_data, dg[iget].dg_len, 0,

49    dg[iget].dg_sa, dg[iget].dg_salen);

50   if (++iget >= QSIZE)

51    iget = 0;

52   /* блокировка SIGIO */

53   Sigprocmask(SIG_BLOCK, &newmask, &oldmask);

54   nqueue--;

55  }

56 }

Инициализация очереди принятых дейтаграмм

27-32 Дескриптор сокета сохраняется в глобальной переменной, поскольку он необходим обработчику сигналов. Происходит инициализация очереди принятых дейтаграмм.

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

Все книги серии Мастер-класс

Секреты резьбы по дереву
Секреты резьбы по дереву

Изделия из древесины и материалов, имитирующих ее текстуру, привычным образом окружают нас в повседневной жизни, поэтому мы относимся к ней как к чему-то обыденному. Но как только ее коснется умелая рука мастера резьбы по дереву, рождается произведение искусства и раскрываются такие качества древесины, как богатая фактура, разнообразие цветов, особая теплота. Эта книга поможет читателю открыть для себя удивительный мир творчества и познать секреты резьбы по дереву. Автор надеется, что начинающие резчики найдут в ней интересный и полезный материал, который позволит им стать мастерами. В приложении представлены рисунки орнаментов и различных узоров, которые на первых порах можно копировать, а по мере приобретения навыка на их основе разрабатывать свои образцы.

Галина Алексеевна Серикова

Сделай сам / Хобби и ремесла / Руководства / Дом и досуг / Словари и Энциклопедии

Похожие книги