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

Здесь есть возможность читать онлайн «Уильям Стивенс - UNIX - разработка сетевых приложений» — ознакомительный отрывок электронной книги совершенно бесплатно, а после прочтения отрывка купить полную версию. В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: Санкт-Петербург, Год выпуска: 2007, ISBN: 2007, Издательство: Питер, Жанр: ОС и Сети, на русском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

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

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «UNIX: разработка сетевых приложений»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

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

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

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «UNIX: разработка сетевых приложений», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать
Обработка сигнала SIGALRM и вызов функции siglongjmp

31-35 Когда сигнал доставлен, мы вызываем функцию siglongjmp. Это заставляет sigsetjmpв функции dg_cliвозвратить значение, равное второму аргументу (1), который должен быть ненулевым. Это приведет к завершению цикла forв функции dg_cli.

Использование функций sigsetjmpи siglongjmpподобным образом гарантирует, что мы не останемся навсегда блокированы в вызове функции recvfromиз-за доставки сигнала в неподходящее время. Однако такое решение создает иную потенциальную проблему. Если сигнал доставляется в тот момент, когда функция printfосуществляет вывод данных, управление будет передано из printfобратно на sigsetjmp. При этом в структурах данных printfмогут возникнуть противоречия. Чтобы предотвратить эту проблему, следует объединить блокирование и разблокирование сигналов, показанное в листинге 20.2, с помощью нелокального оператора goto.

Применение IPC в обработчике сигнала функции

Существует еще один корректный путь решения нашей проблемы. Вместо того чтобы просто возвращать управление и, как мы надеемся, прерывать блокированную функцию recvfrom, наш обработчик сигнала при помощи средств IPC (Interprocess Communications — взаимодействие процессов) может сообщить функции dg_cliо том, что время таймера истекло. Это аналогично предложению, сделанному нами раньше, когда обработчик сигнала устанавливал глобальную переменную had_alarmпо истечении времени таймера. Глобальная переменная использовалась как некая разновидность IPC (поскольку она была доступна и нашей функции, и обработчику сигнала). Однако при таком решении наша функция должна была проверять эту переменную, что могло привести к проблемам синхронизации в том случае, когда сигнал доставлялся приблизительно в это же время.

Листинг 20.6 демонстрирует использование канала внутри процесса. Обработчик сигналов записывает в канал 1 байт, когда истекает время таймера, а наша функция dg_cliсчитывает этот байт, чтобы определить, когда завершить свой цикл for. Что замечательно в этом решении — проверка готовности канала осуществляется функцией select. С ее помощью мы проверяем, готов ли к считыванию сокет или канал.

Листинг 20.6. Использование канала в качестве IPC между обработчиком сигнала и нашей функцией

//bcast/dgclibcast6.c

1 #include "unp.h"

2 static void recvfrom_alarm(int);

3 static int pipefd[2];

4 void

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

6 {

7 int n, maxfdp1;

8 const int on = 1;

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

10 fd_set rset;

11 socklen_t len;

12 struct sockaddr *preply_addr;

13 preply_addr = Malloc(servlen);

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

15 Pipe(pipefd);

16 maxfdp1 = max(sockfd, pipefd[0]) + 1;

17 FD_ZERO(&rset);

18 Signal(SIGALRM, recvfrom_alarm);

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

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

21 alarm(5);

22 for (;;) {

23 FD_SET(sockfd, &rset);

24 FD_SET(pipefd[0], &rset);

25 if ((n = select(maxfdp1, &rset, NULL, NULL, NULL))

26 if (errno == EINTR)

27 continue;

28 else

29 err_sys("select error");

30 }

31 if (FD_ISSET(sockfd, &rset)) {

32 len = servlen;

33 n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr,

34 &len);

35 recvline[n] = 0; /* null terminate */

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

37 Sock_ntop_host(preply_addr, len), recvline);

38 }

39 if (FD_ISSET(pipefd[0], &rset)) {

40 Read(pipefd[0], &n, 1); /* истекшее время */

41 break;

42 }

43 }

44 }

45 free(preply_addr);

46 }

47 static void

48 recvfrom_alarm(int signo)

49 {

50 Write(pipefd[1], "", 1); /* в канал пишется один нулевой байт */

51 return;

52 }

Создание канала

15 Мы создаем обычный канал Unix. Возвращаются два дескриптора: pipefd[0]доступен для чтения, а pipefd[0] — для записи.

ПРИМЕЧАНИЕ

Мы могли бы использовать функцию socketpair и получить двусторонний канал. В некоторых системах, особенно SVR4, обычный канал Unix всегда является двусторонним, и мы можем и читать, и записывать на любом конце этого канала.

Функция select на сокете и считывающем конце канала

23-30 Мы вызываем функцию selectи на сокете, и на считывающем конце канала.

47-52 Когда доставляется сигнал SIGALRM, наш обработчик сигналов записывает в канал 1 байт, в результате чего считывающий конец канала становится готовым для чтения. Наш обработчик сигнала также возвращает управление, возможно, прерывая функцию select. Следовательно, если функция selectвозвращает ошибку EINTR, мы игнорируем эту ошибку, зная, что считывающий конец канала также готов для чтения, что завершит цикл for.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

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

Представляем Вашему вниманию похожие книги на «UNIX: разработка сетевых приложений» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


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

Обсуждение, отзывы о книге «UNIX: разработка сетевых приложений» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x