Шрифт:
7 n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name);
8 Writen(fptr->f_fd, line, n);
9 printf("wrote %d bytes for %s\n", n, fptr->f_name);
10 fptr->f_flags = F_READING; /* сброс F_CONNECTING */
11 FD_SET(fptr->f_fd, &rset); /* прочитаем ответ сервера */
12 if (fptr->f_fd > maxfd)
13 maxfd = fptr->f_fd;
14 }
Создание команды и ее отправка
7-9
Команда создается и пишется в сокет. Установка флагов
10-13
Устанавливается флаг F_READING
, при этом также сбрасывается флаг F_CONNECTING
(если он установлен). Это указывает основному циклу, что данный дескриптор готов для ввода. Также включается дескриптор в наборе чтения, и при необходимости обновляется значение maxfd
. Теперь мы возвращаемся в функцию
main
, показанную в листинге 16.13, начиная с того места, где закончили в листинге 16.9. Это основной цикл программы: пока имеется ненулевое количество файлов для обработки (значение nlefttoread
больше нуля), устанавливается, если это возможно, другое соединение и затем вызывается функция select
для всех активных дескрипторов, обрабатывающая как завершение неблокируемых соединений, так и прием данных. Можем ли мы инициировать другое соединение?
24-35
Если мы не дошли до заданного предела одновременных соединений и есть дополнительные соединения, которые нужно установить, мы ищем еще не обработанный файл (на него указывает нулевое значение f_flags
) и вызываем функцию start_connect
для инициирования соединения. Число активных соединений увеличивается на единицу ( nconn
), а число соединений, которые нужно установить, на единицу уменьшается ( nlefttoconn
). Функция select: ожидание событий
36-37
Функция select
ожидает готовности сокета либо для чтения, либо для записи. Дескрипторы, для которых в настоящий момент происходит установление соединения (неблокируемая функция connect
находится в процессе выполнения), будут включены в обоих наборах, в то время как дескрипторы с завершенным соединением, ожидающие данных от сервера, будут включены только в наборе чтения. Листинг 16.13. Основной цикл функции main
//nonblock/web.c
24 while (nlefttoread > 0) {
25 while (nconn < maxnconn && nlefttoconn > 0) {
26 /* find a file to read */
27 for (i =0; i < nfiles; i++)
28 if (file[i].f_flags == 0)
29 break;
30 if (i == nfiles)
31 err_quit("nlefttoconn = %d but nothing found", nlefttoconn);
32 start_connect(&file[i]);
33 nconn++;
34 nlefttoconn--;
35 }
36 rs = rset:
37 ws = wset;
38 n = Select(maxfd + 1, &rs, &ws, NULL, NULL);
39 for (i = 0; i < nfiles; i++) {
40 flags = file[i].f_flags;
41 if (flags == 0 || flags & F_DONE)
42 continue;
43 fd = file[i].f_fd;
44 if (flags & F_CONNECTING &&
45 (FD_ISSET(fd, &rs) || FD_ISSET(fd, &ws))) {
46 n = sizeof(error);
47 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &n) < 0 ||