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

Тут можно читать онлайн Уильям Стивенс - UNIX: разработка сетевых приложений - бесплатно ознакомительный отрывок. Жанр: comp-osnet, издательство Питер, год 2007. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    UNIX: разработка сетевых приложений
  • Автор:
  • Жанр:
  • Издательство:
    Питер
  • Год:
    2007
  • Город:
    Санкт-Петербург
  • ISBN:
    5-94723-991-4
  • Рейтинг:
    4.33/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

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

UNIX: разработка сетевых приложений - описание и краткое содержание, автор Уильям Стивенс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

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

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

UNIX: разработка сетевых приложений - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Уильям Стивенс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

2. Блокирование при ожидании ввода-вывода в функции select, имеющей встроенное ограничение времени, вместо блокирования в вызове функции readили write.

3. Использование более новых параметров сокета — SO_RCVTIMEOи SO_SNDTIMEO. Проблема при использовании этого подхода заключается в том, что не все реализации поддерживают новые параметры сокетов.

Все три технологии работают с функциями ввода и вывода (такими как read, writeи их вариациями, например recvfromи sendto), но нам также хотелось бы иметь технологию, работающую с функцией connect, поскольку процесс соединения TCP может занять длительное время (обычно 75 с). Функцию selectможно использовать для установки тайм-аута функции connect, только когда сокет находится в неблокируемом режиме (который мы рассматриваем в разделе 16.3), а параметры сокетов, устанавливающие тайм-аут, не работают с функцией connect. Мы также должны отметить, что первые две технологии работают с любым дескриптором, в то время как третья технология только с дескрипторами сокетов.

Теперь мы представим примеры применения всех трех технологий.

Тайм-аут для функции connect (сигнал SIGALRM)

В листинге 14.1 [1] Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com. показана наша функция connect_timeo, вызывающая функцию connect с ограничением по времени, заданным вызывающим процессом. Первые три аргумента — это аргументы, которых требует функция connect, а четвертый — это длительность ожидания в секундах.

Листинг 14.1. Функция connect с тайм-аутом

//lib/connect_timeo.c

1 #include "unp.h"

2 static void connect_alarm(int);

3 int

4 connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int nsec)

5 {

6 Sigfunc *sigfunc;

7 int n;

8 sigfunc = Signal(SIGALRM, connect_alarm);

9 if (alarm(nsec) != 0)

10 err_msg("connect_timeo: alarm was already set");

11 if ((n = connect(sockfd, saptr, salen)) < 0) {

12 close(sockfd);

13 if (errno == EINTR)

14 errno = ETIMEDOUT;

15 }

16 alarm(0); /* отключение alarm */

17 Signal(SIGALRM, sigfunc); /* восстанавливаем прежний обработчик

сигнала */

18 return (n);

19 }

20 static void

21 connect_alarm(int signo)

22 {

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

24 }

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

8 Для SIGALRMустанавливается обработчик сигнала. Текущий обработчик сигнала (если таковой имеется) сохраняется, и таким образом мы можем восстановить его в конце функции.

Установка таймера

9-10 Таймер для процесса устанавливается на время (число секунд), заданное вызывающим процессом. Возвращаемое значение функции alarm— это число секунд, остающихся в таймере для процесса (если он уже установлен для процесса) в настоящий момент или 0 (если таймер не был установлен прежде). В первом случае мы выводим сообщение с предупреждением, поскольку мы стираем предыдущую установку таймера (см. упражнение 14.2).

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

11-15 Вызывается функция connect, и если функция прерывается ( EINTR), мы присваиваем переменной errno значение ETIMEDOUT. Сокет закрывается, чтобы не допустить продолжения трехэтапного рукопожатия.

Выключение таймера и восстановление предыдущего обработчика сигнала

16-18 Таймер при обнулении выключается, и восстанавливается предыдущий обработчик сигналов (если таковой имеется).

Обработка сигнала SIGALRM

20-24 Обработчик сигнала просто возвращает управление. Предполагается, что это прервет ожидание функции connect, заставив ее возвратить ошибку EINTR. Вспомните нашу функцию signal(см. листинг 5.5), которая не устанавливает флага SA_RESTART, когда перехватываемый сигнал — это сигнал SIGALRM.

Одним из важных моментов в этом примере является то, что мы всегда можем сократить период ожидания для функции connect, используя эту технологию, но мы не можем увеличить период, заданный для ядра. В Беркли-ядре тайм-аут для функции connectобычно равен 75 с. Мы можем задать меньшее значение для нашей функции, допустим 10, но если мы задаем большее значение, скажем 80, тайм- аут самой функции connectвсе равно составит 75 с.

Другой важный момент в данном примере — то, что мы используем возможность прерывания системного вызова ( connect) для того, чтобы возвратить управление, прежде чем истечет время ожидания ядра. Такой подход допустим, когда мы выполняем системный вызов и можем обработать возвращение ошибки EINTR. Но в разделе 29.7 мы встретимся с библиотечной функцией, выполняющей системный вызов, которая сама выполняет заново системный вызов при возвращении ошибки EINTR. Мы можем продолжать работать с сигналом SIGALRMи в этом случае, но в листинге 29.6 мы увидим, что нам придется воспользоваться функциями sigsetjmpи siglongjmp, поскольку библиотечная функция игнорирует ошибку EINTR.

Тайм-аут для функции recvfrom (сигнал SIGALRM)

В листинге 14.2 показана новая версия функции dg_cli, приведенной в листинге 8.4, в которую добавлен вызов функции alarmдля прерывания функции recvfrom при отсутствии ответа в течение 5 с.

Листинг 14.2. Функция dg_cli, в которой при установке тайм-аута для функции recvfrom используется функция alarm

//advio/dgclitimeo3.c

1 #include "unp.h"

2 static void signalrm(int);

3 void

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

5 {

6 int n;

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

8 Signal(SIGALRM, signalrm);

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

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

11 alarm(5);

12 if ((n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL)) < 0) {

13 if (errno == EINTR)

14 fprintf(stderr, "socket timeout\n");

15 else

16 err_sys("recvfrom error");

17 } else {

18 alarm(0);

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

20 Fputs(recvline, stdout);

21 }

22 }

23 }

24 static void

25 sig_alrm(int signo)

26 {

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

28 }

Обработка тайм-аута из функции recvfrom

8-22 Мы устанавливаем обработчик для сигнала SIGALRMи затем вызываем функцию alarmдля 5-секундного тайм-аута при каждом вызове функции recvfrom. Если функция recvfromпрерывается нашим обработчиком сигнала, мы выводим сообщение об ошибке и продолжаем работу. Если получена строка от сервера, мы отключаем функцию alarm и выводим ответ.

Обработчик сигнала SIGALRM

24-28 Наш обработчик сигналов возвращает управление, прерывая блокированную функцию recvfrom.

Этот пример работает корректно, потому что каждый раз, когда мы устанавливаем функцию alarm, мы читаем только один ответ. В разделе 20.4 мы попытаемся использовать ту же технологию, но поскольку мы будем считывать множество ответов для данной функции alarm, возникнет ситуация гонок, которую нам придется разрешить.

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

Интервал:

Закладка:

Сделать


Уильям Стивенс читать все книги автора по порядку

Уильям Стивенс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


Отзывы читателей о книге UNIX: разработка сетевых приложений, автор: Уильям Стивенс. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x