Чтение онлайн

на главную

Жанры

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

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

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

В листинге 14.1 [1] показана наша функция

connect_timeo
, вызывающая функцию connect с ограничением по времени, заданным вызывающим процессом. Первые три аргумента — это аргументы, которых требует функция
connect
, а четвертый — это длительность ожидания в секундах.

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

1

Все

исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.

//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) {

Поделиться:
Популярные книги

Штурм Земли

Семенов Павел
8. Пробуждение Системы
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Штурм Земли

Чехов. Книга 3

Гоблин (MeXXanik)
3. Адвокат Чехов
Фантастика:
альтернативная история
5.00
рейтинг книги
Чехов. Книга 3

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Последний попаданец 11. Финал. Часть 1

Зубов Константин
11. Последний попаданец
Фантастика:
фэнтези
юмористическое фэнтези
рпг
5.00
рейтинг книги
Последний попаданец 11. Финал. Часть 1

Право налево

Зика Натаэль
Любовные романы:
современные любовные романы
8.38
рейтинг книги
Право налево

Комбинация

Ланцов Михаил Алексеевич
2. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Комбинация

Прометей: Неандерталец

Рави Ивар
4. Прометей
Фантастика:
героическая фантастика
альтернативная история
7.88
рейтинг книги
Прометей: Неандерталец

Идеальный мир для Лекаря 16

Сапфир Олег
16. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 16

Двойня для босса. Стерильные чувства

Лесневская Вероника
Любовные романы:
современные любовные романы
6.90
рейтинг книги
Двойня для босса. Стерильные чувства

Деспот

Шагаева Наталья
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Деспот

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Возвышение Меркурия. Книга 13

Кронос Александр
13. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 13

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

Титан империи 6

Артемов Александр Александрович
6. Титан Империи
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Титан империи 6