UNIX: разработка сетевых приложений, стр. 186
19-23maxfdselectnlefttoreadnlefttoconnnconnВ листинге 16.10 показана функция
home_pageЛистинг 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 }Установление соединения с сервером
7tcp_connectОтправка команды HTTP серверу, чтение ответа
8-17GET/Следующая функция,
start_connectЛистинг 16.11. Инициирование неблокируемой функции connect
//nonblock/start_connect.c 1 #include "web.h" 2 void 3 start_connect(struct file *fptr) 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_connect for %s, fd %d\n", fptr->f_name, fd);11 /* отключаем блокирование сокета */12 flags = Fcntl(fd, F_GETFL, 0);13 Fcntl(fd, F_SETFL, flags | O_NONBLOCK);14 /* инициируем неблокируемое соединение с сервером */15 if ((n = connected, ai->ai_addr, ai->ai_addrlen)) < 0) {16 if (errno != EINPROGRESS)17 err_sys("nonblocking connect error");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-13host_servaddrinfoВызов неблокируемой функции connect
14-22connectF_CONNECTINGselectmaxfdОбработка завершения установления соединения
23-24connectwrite_get_cmdМы делаем сокет неблокируемым для функции
connectwritewritenreadselect