UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Мы также рассказываем о том, как определить, сколько данных находится в приемном буфере сокета и как использовать с сокетами стандартную библиотеку ввода-вывода С, и обсуждаем более совершенные способы ожидания событий.
14.2. Тайм-ауты сокета
Существует три способа установки тайм-аута для операции ввода-вывода через сокет.
1. Вызов функции
alarm
SIGALRM
alarm
2. Блокирование при ожидании ввода-вывода в функции
select
read
write
3. Использование более новых параметров сокета —
SO_RCVTIMEO
SO_SNDTIMEO
Все три технологии работают с функциями ввода и вывода (такими как
read
write
recvfrom
sendto
connect
select
connect
connect
Теперь мы представим примеры применения всех трех технологий.
Тайм-аут для функции connect (сигнал SIGALRM)
В листинге 14.1 [1] показана наша функция
connect_timeo
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
11-15
connect
EINTR
ETIMEDOUT
16-18
20-24
connect
EINTR
signal
SA_RESTART
SIGALRM
Одним из важных моментов в этом примере является то, что мы всегда можем сократить период ожидания для функции
connect
connect
connect
Другой важный момент в данном примере — то, что мы используем возможность прерывания системного вызова (
connect
EINTR
EINTR
SIGALRM
sigsetjmp
siglongjmp
EINTR