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

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

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

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

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

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

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

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

Интервал:

Закладка:

Сделать

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

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

22 Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);

23 alarm(5);

24 for (;;) {

25 FD_SET(sockfd, &rset);

26 n = pselect(sockfd + 1, &rset, NULL, NULL, NULL, &sigset_empty);

27 if (n

28 if (errno == EINTR)

29 break;

30 else

31 err_sys("pselect error");

32 } else if (n != 1)

33 err_sys("pselect error; returned %d", n);

34 len = servlen;

35 n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);

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

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

38 Sock_ntop_host(preply_addr, len), recvline);

39 }

40 }

41 free(preply_addr);

42 }

43 static void

44 recvfrom_alarm(int signo)

45 {

46 return; /* просто прерываем recvfrom() */

47 }

22-23 Мы блокируем сигнал SIGALRMи вызываем функцию pselect. Последний аргумент этой функции — указатель на нашу переменную sigset_empty, являющуюся набором сигналов, в котором нет блокированных сигналов (все сигналы разблокированы). Функция pselectсохранит текущую маску сигналов (которая блокирует SIGALRM), проверит заданные дескрипторы, заблокируется при необходимости с маской сигналов, установленной в пустой набор, но перед завершением функции маска сигналов процесса будет переустановлена в исходное значение, которое она имела при вызове функции pselect. Ключ к пониманию функции pselectв том, что установка маски сигналов, проверка дескрипторов и переустановка маски сигнала — это атомарные операции по отношению к вызывающему процессу.

34-38 Если наш сокет готов для чтения, мы вызываем функцию recvfrom, зная, что она не заблокируется.

Как мы упоминали в разделе 6.9, функция pselect— относительно новая среди других, описываемых спецификацией POSIX. Из всех систем, показанных на рис. 1.7, эту функцию поддерживают только FreeBSD и Linux. Тем не менее в листинге 20.4 представлена простая, хотя и некорректная ее реализация. Мы приводим ее здесь, несмотря на некорректность, чтобы продемонстрировать три стадии решения: установку маски сигнала в значение, заданное вызывающей функцией, с сохранением текущей маски, проверку дескрипторов и переустановку маски сигнала.

Листинг 20.4. Простая некорректная реализация функции pselect

//lib/pselect.c

9 #include "unp.h"

10 int

11 pselect(int nfds, fd_set *rset, fd_set *wset, fd_set *xset,

12 const struct timespec *ts, const sigset_t *sigmask)

13 {

14 int n;

15 struct timeval tv;

16 sigset_t savemask;

17 if (ts != NULL) {

18 tv.tv_sec = ts->tv_sec;

19 tv.tv_usec = ts->tv_nsec / 1000; /* наносекунды -> микросекунды */

20 }

21 sigprocmask(SIG_SETMASK, sigmask, &savemask); /* маска вызывающего

процесса */

22 n = select(nfds, rset, wset, xset., (ts == NULL) ? NULL : &tv);

23 sigprocmask(SIG_SETMASK, &savemask, NULL); /* восстанавливаем

исходную маску */

24 return (n);

25 }

Использование функций sigsetjmp и siglongjmp

Нашу проблему можно решить корректно, если отказаться от прерывания блокированного системного вызова обработчиком сигнала, вместо этого вызвав из обработчика сигнала функцию siglongjmp. Этот метод называется нелокальным оператором goto ( nonlocal goto ), поскольку мы можем использовать его для перехода из одной функции в другую. В листинге 20.5 проиллюстрирована эта технология.

Листинг 20.5. Вызов функций sigsetjmp и siglongjmp из обработчика сигнала

//bcast/dgclibcast5.c

1 #include "unp.h"

2 #include

3 static void recvfrom_alarm(int);

4 static sigjmp_buf jmpbuf;

5 void

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

7 {

8 int n;

9 const int on = 1;

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

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 Signal(SIGALRM, recvfrom_alarm);

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

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

18 alarm(5);

19 for (;;) {

20 if (sigsetjmp(jmpbuf, 1) != 0)

21 break;

22 len = servlen;

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

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

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

26 Sock_ntop_host(preply_addr, len), recvline);

27 }

28 }

29 free(preply_addr);

30 }

31 static void

32 recvfrom_alarm(int signo)

33 {

34 siglongjmp(jmpbuf, 1);

35 }

Размещение буфера перехода в памяти

4 Мы выделяем буфер перехода, который будет использовать наша функция и ее обработчик сигнала.

Вызов функции sigsetjmp

20-23 Когда мы вызываем функцию sigsetjmpнепосредственно из нашей функции dg_cli, она устанавливает буфер перехода и возвращает нуль. Мы продолжаем работать дальше и вызываем функцию recvfrom.

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

Интервал:

Закладка:

Сделать

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

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


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

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

x