UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Мы также рассказываем о том, как определить, сколько данных находится в приемном буфере сокета и как использовать с сокетами стандартную библиотеку ввода-вывода С, и обсуждаем более совершенные способы ожидания событий.
14.2. Тайм-ауты сокета
Существует три способа установки тайм-аута для операции ввода-вывода через сокет.
1. Вызов функции
alarmSIGALRMalarm2. Блокирование при ожидании ввода-вывода в функции
selectreadwrite3. Использование более новых параметров сокета —
SO_RCVTIMEOSO_SNDTIMEOВсе три технологии работают с функциями ввода и вывода (такими как
readwriterecvfromsendtoconnectselectconnectconnectТеперь мы представим примеры применения всех трех технологий.
Тайм-аут для функции connect (сигнал SIGALRM)
В листинге 14.1 [1] показана наша функция
connect_timeoconnectЛистинг 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 void21 connect_alarm(int signo)22 {23 return; /* просто прерываем connect() */24 }8SIGALRM9-10alarm11-15connectEINTRETIMEDOUT16-1820-24connectEINTRsignalSA_RESTARTSIGALRMОдним из важных моментов в этом примере является то, что мы всегда можем сократить период ожидания для функции
connectconnectconnectДругой важный момент в данном примере — то, что мы используем возможность прерывания системного вызова (
connectEINTREINTRSIGALRMsigsetjmpsiglongjmpEINTR
