Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

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
Дескриптор сокета сохраняется в глобальной переменной, поскольку он необходим обработчику сигналов. Происходит инициализация очереди принятых дейтаграмм.

Установка обработчиков сигналов и флагов сокетов

33-37
Для сигналов
SIGHUP
(он используется для диагностических целей) и
SIGIO
устанавливаются обработчики. С помощью функции
fcntl
задается владелец сокета, а с помощью функции
ioctl
устанавливаются флаги ввода-вывода, управляемого сигналом, и неблокируемого ввода-вывода.

  • Читать дальше
  • 1
  • ...
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: