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

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

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

Мы демонстрируем вторую технологию для установки тайм-аута (использование функции select) в листинге 14.3. Здесь показана наша функция readable_timeo, которая ждет, когда дескриптор станет готов для чтения, но не более заданного числа секунд.

Листинг 14.3. Функция readable_timeo: ожидание, когда дескриптор станет готов для чтения

//lib/readable_timео.c
 1 #include "unp.h"
 2 int
 3 readable_timeo(int fd, int sec)
 4 {
 5  fd_set rset;
 6  struct timeval tv;
 7  FD_ZERO(&rset);
 8  FD_SET(fd, &rset);
 9  tv.tv_sec = sec;
10  tv.tv_usec = 0;
11  return (select(fd + 1, &rset, NULL, NULL, &tv));
12  /* > если дескриптор готов для чтения */
13 }

Подготовка аргументов для функции select

7-10 В наборе дескрипторов для чтения включается бит, соответствующий данному дескриптору. В структуре timeval устанавливается время (число секунд), в течение которого вызывающий процесс готов ждать.

Блокирование в функции select

11-12 Функция select ждет, когда дескриптор станет готов для чтения или истечет заданное время ожидания. Возвращаемое значение этой функции — это возвращаемое значение функции select: -1 в случае ошибки, 0, если истекло время ожидания, и положительное значение, задающее число готовых дескрипторов, если таковые появились.

Эта функция не выполняет операции чтения — она просто ждет, когда дескриптор будет готов к чтению. Следовательно, эту функцию можно использовать с любым типом сокета — TCP или UDP.

Создание аналогичной функции, называемой writable_timeo, тривиально. Эта функция ждет, когда дескриптор будет готов для записи.

Мы используем эту функцию в листинге 14.4, где показана еще одна версия нашей функции dg_cli, приведенной в листинге 8.4. Эта новая версия вызывает функцию recvfrom, только когда наша функция readable_timeo возвращает положительное значение.

Мы не вызываем функцию recvfrom, пока функция readable_timeo не сообщит нам, что дескриптор готов для чтения. Тем самым мы гарантируем, что функция recvfrom не заблокируется.

Листинг 14.4. Функция dg_cli, вызывающая функцию readable_timeo для установки тайм-аута

//advio/dgclitimeo1.c
 1 #include "unp.h"
 2 void
 3 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
 4 {
 5  int n;
 6  char sendline[MAXLINE], recvline[MAXLINE + 1];
 7  while (Fgets(sendline, MAXLINE, fp) != NULL) {
 8   Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
 9   if (Readable_timeo(sockfd, 5) == 0) {
10    fprintf(stderr, "socket timeoutn");
11   } else {
12    n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);
13    recvline[n] = 0; /* завершающий нуль */
14    Fputs(recvline, stdout);
15   }
16  }
17 }

Оглавление книги


Генерация: 1.224. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз