Шрифт:
Определение глобальных переменных и прототипов функций
14-20
Мы определяем глобальные переменные и прототипы для наших функций, которые мы вскоре опишем. Листинг 16.9. Первая часть программы одновременного выполнения функций connect: глобальные переменные и начало функции main
//nonblock/web.c
1 #include "web.h"
2 int
3 main(int argc, char **argv)
4 {
5 int i, fd, n, maxnconn, flags, error;
6 char buf[MAXLINE];
7 fd_set rs, ws;
8 if (argc < 5)
9 err_quit("usage: web <#conns> <hostname> <homepage> <file1> ...");
10 maxnconn = atoi(argv[1]);
11 nfiles = min(argc - 4, MAXFILES);
12 for (i = 0; i < nfiles; i++) {
13 file[i].f_name = argv[i + 4];
14 file[i].f_host = argv[2];
15 file[i].f_flags = 0;
16 }
17 printf("nfiles = %d\n", nfiles);
18 home_page(argv[2], argv[3]);
19 FD_ZERO(&rset);
20 FD_ZERO(&wset);
21 maxfd = -1;
22 nlefttoread = nlefttoconn = nfiles;
23 nconn = 0;
Обработка аргументов командной строки
11-17
Структуры file
заполняются соответствующей информацией из аргументов командной строки. Чтение домашней страницы
18
Функция home_page
, которую мы показываем в следующем листинге, создает соединение TCP, посылает команду серверу и затем читает домашнюю страницу. Это первое соединение, которое выполняется самостоятельно, до того как мы начнем устанавливать параллельные соединения. Инициализация глобальных переменных
19-23
Инициализируются два набора дескрипторов, по одному для чтения и для записи. maxfd
— это максимальный дескриптор для функции select
(который мы инициализируем значением -1, поскольку дескрипторы неотрицательны), nlefttoread
— число файлов, которые осталось прочитать (когда это значение становится нулевым, чтение заканчивается), nlefttoconn
— это количество файлов, для которых пока еще требуется соединение TCP, a nconn
— это число соединений, открытых в настоящий момент (оно никогда не может превышать первый аргумент командной строки). В листинге 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_connect(host, SERV); /* блокируемая функция connect */
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 page\n", n);
14 /* обрабатываем полученные данные */
15 }
16 printf("end-of-file on home page\n");
17 Close(fd);
18 }
Установление соединения с сервером
7
Наша функция tcp_connect
устанавливает соединение с сервером. Отправка команды HTTP серверу, чтение ответа
8-17
Запускается команда HTTP GET
для домашней страницы (часто обозначается символом /
). Читается ответ (с ответом мы в данном случае ничего не делаем), и соединение закрывается.