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

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

Шрифт:

//bcast/dgclibcast3.c

1 #include "unp.h"

2 static void recvfrom_alarm(int);

3 void

4 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)

5 {

6 int n;

7 const int on = 1;

8 char sendline[MAXLINE], recvline[MAXLINE + 1];

9 sigset_t sigset_alrm;

10 socklen_t len;

11 struct sockaddr *preply_addr;

12 preply_addr = Malloc(servlen);

13 Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

14 Sigemptyset(&sigset_alrm);

15 Sigaddset(&sigset_alrm, SIGALRM);

16 Signal(SIGALRM, recvfrom_alarm);

17 while (Fgets(sendline, MAXLINE, fp) != NULL) {

18 Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);

19 alarm(5);

20 for (;;) {

21 len = servlen;

22 Sigprocmask(SIG_UNBLOCK, &sigset_alrm, NULL);

23 n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);

24 Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);

25 if (n < 0) {

26 if (errno == EINTR)

27 break; /* окончание ожидания ответа */

28 else

29 err_sys("recvfrom error");

30 } else {

31 recvline[n] = 0; /* завершающий нуль */

32 printf("from %s: %s",

33 Sock_ntop_host(preply_addr, len), recvline);

34 }

35 }

36 }

37 free(preply_addr);

38 }

39 static void

40 recvfrom_alarm(int signo)

41 {

42 return; /* выход из recvfrom */

43 }

Объявление набора сигналов и инициализация

14-15
Мы объявляем набор сигналов, инициализируем его как пустой набор (
sigemptyset
) и включаем бит, соответствующий сигналу
SIGALRM
(
sigaddset
).

Разблокирование и блокирование сигнала

21-24
Перед вызовом функции
recvfrom
мы разблокируем сигнал (с тем, чтобы он мог быть доставлен, пока наша программа блокирована), а затем блокируем его, как только завершается функция
recvfrom
. Если сигнал генерируется (истекает время таймера), когда сигнал блокирован, то ядро запоминает этот факт, но доставить сигнал (то есть вызвать наш обработчик) не может, пока сигнал не будет разблокирован. В этом состоит принципиальная разница между генерациейсигнала и его доставкой. В главе 10 [110] предоставлена более подробная информация обо всех аспектах обработки сигналов POSIX.

Если мы откомпилируем и запустим эту программу, нам будет казаться, что она работает нормально, но все программы, порождающие ситуацию гонок, большую часть времени работают без каких-либо проблем! Проблема остается: разблокирование сигнала, вызов функции

recvfrom
и блокирование сигнала — все эти действия являются независимыми системными вызовами. Будем считать, что функция
recvfrom
возвращает последний ответ на нашу дейтаграмму, а сигнал доставляется между вызовом функции
recvfrom
и блокированием сигнала. Следующий вызов функции
recvfrom
заблокируется навсегда. Мы ограничили размер окна, но проблема осталась.

  • Читать дальше
  • 1
  • ...
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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