Добавить в цитаты Настройки чтения

Страница 186 из 399

19-23 Инициализируются два набора дескрипторов, по одному для чтения и для записи. maxfd — это максимальный дескриптор для функции select (который мы инициализируем значением -1, поскольку дескрипторы неотрицательны), nlefttoread — число файлов, которые осталось прочитать (когда это значение становится нулевым, чтение заканчивается), nlefttoco

В листинге 16.10 показана функция home_page, вызываемая один раз, когда начинается выполнение функции main.

Листинг 16.10. Функция home_page

//nonblock/home_page.c

 1 #include "web.h"

 2 void

 3 home_page(const char *host, const char *fname)

 4 {

 5  int fd, n;

 6  char line[MAXLINE];

 7  fd = Tcp_co

 8  n = snprintf(line, sizeof(line), GET_CMD, fname);

 9  Writen(fd, line, n);

10  for (;;) {

11   if ((n = Read(fd, line, MAXLINE)) == 0)

12    break; /* сервер закрыл соединение */

13   printf("read %d bytes of home pagen", n);

14   /* обрабатываем полученные данные */

15  }

16  printf("end-of-file on home pagen");

17  Close(fd);

18 }

7 Наша функция tcp_co

8-17 Запускается команда HTTP GET для домашней страницы (часто обозначается символом /). Читается ответ (с ответом мы в данном случае ничего не делаем), и соединение закрывается.

Следующая функция, start_co

Листинг 16.11. Инициирование неблокируемой функции co

//nonblock/start_co

 1 #include "web.h"

 2 void

 3 start_co

 4 {

 5  int fd, flags, n;

 6  struct addrinfo *ai;

 7  ai = Host_serv(fptr->f_host, SERV, 0, SOCK_STREAM);

 8  fd = Socket(ai->ai_family; ai->ai_socktype, ai->ai_protocol);

 9  fptr->f_fd = fd;

10  printf("start_co

11  /* отключаем блокирование сокета */

12  flags = Fcntl(fd, F_GETFL, 0);

13  Fcntl(fd, F_SETFL, flags | O_NONBLOCK);

14  /* инициируем неблокируемое соединение с сервером */

15  if ((n = co

16   if (errno != EINPROGRESS)

17    err_sys("nonblocking co

18   fptr->f_flags = F_CONNECTING;

19   FD_SET(fd, &rset); /* включаем дескриптор сокета в наборе чтения

                           и записи */

20   FD_SET(fd, &wset);

21   if (fd > maxfd)

22    maxfd = fd;

23  } else if (n >= 0) /* соединение уже установлено */

24   write_get_cmd(fptr); /* отправляем команду GET серверу */

25 }

7-13 Мы вызываем нашу функцию host_serv для поиска и преобразования имени узла и имени службы. Она возвращает указатель на массив структур addrinfo. Мы используем только первую структуру. Создается сокет TCP, и он становится неблокируемым.

14-22 Вызывается неблокируемая функция co

23-24 Если функция co

Мы делаем сокет неблокируемым для функции co