UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
В листинге 16.12 показана функция
write_get_cmd
Листинг 16.12. Отправка команды HTTP GET серверу
//nonblock/write_get_cmd.c
1 #include "web.h"
2 void
3 write_get_cmd(struct file *fptr)
4 {
5 int n;
6 char line[MAXLINE];
7 n = snprintf(line, sizeof(line), GET_CMD, fptr->f_name);
8 Writen(fptr->f_fd, line, n);
9 printf("wrote %d bytes for %sn", 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
nlefttoread
select
24-35
f_flags
start_connect
nconn
nlefttoconn
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 ||
48 error != 0) {
49 err_ret("nonblocking connect failed
50 for %s", file[i].f_name);
51 }
52 /* соединение установлено */
53 printf("connection established for %sn", file[i].f_name);
54 FD_CLR(fd, &wset); /* отключаем запись в этот сокет */
55 write_get_cmd(&file[i]); /* передаем команду GET */
56 } else if (flags & F_READING && FD_ISSET(fd, &rs)) {
57 if ((n = Read(fd, buf, sizeof(buf))) == 0) {
58 printf("end-of-file on %sn", file[i].f_name);
59 Close(fd);
60 file[i].f_flags = F_DONE; /* сбрасывает флаг F_READING */
61 FD_CLR(fd, &rset);
62 nconn--;
63 nlefttoread--;
64 } else {
65 printf("read %d bytes from %sn", n, file[i].f_name);
66 }