UNIX: разработка сетевых приложений
Шрифт:
Листинг 30.18. Функция main, использующая передачу дескриптора
//server/serv05.c
1 #include "unp.h"
2 #include "child.h"
3 static int nchildren;
4 int
5 main(int argc, char **argv)
6 {
7 int listenfd, i, navail, maxfd, nsel, connfd, rc;
8 void sig_int(int);
9 pid_t child_make(int, int, int);
10 ssize_t n;
11 fd_set rset, masterset;
12 socklen_t addrlen, clilen;
13 struct sockaddr *cliaddr;
14 if (argc == 3)
15 listenfd = Tcp_listen(NULL, argv[1], &addrlen);
16 else if (argc == 4)
17 listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
18 else
19 err_quit("usage; serv05 [ <host> ] <port#> <#children>");
20 FD_ZERO(&masterset);
21 FD_SET(listenfd, &masterset);
22 maxfd = listenfd;
23 cliaddr = Malloc(addrlen);
24 nchildren = atoi(argv[argc - 1]);
25 navail = nchildren;
26 cptr = Calloc(nchildren, sizeof(Child));
27 /*
предварительное создание дочерних процессов */
28 for (i = 0; i < nchildren; i++) {
29 child_make(i, listenfd, addrlen); /* родительский процесс
завершается */
30 FD_SET(cptr[i].child_pipefd, &masterset);
31 maxfd = max(maxfd, cptr[i].child_pipefd);
32 }
33 Signal(SIGINT, sig_int);
34 for (;;) {
35 rset = masterset;
36 if (navail <= 0)
37 FD_CLR(listenfd, &rset); /*
выключаем, если нет свободных
дочерних процессов */
38 nsel = Select(maxfd + 1, &rset, NULL, NULL, NULL);
39 /* проверка новых соединений */
40 if (FD_ISSET(listenfd, &rset)) {
41 clilen = addrlen;
42 connfd = Accept(listenfd, cliaddr, &clilen);
43 for (i = 0; i < nchildren; i++)
44 if (cptr[i].child_status == 0)
45 break; /* свободный */
46 if (i == nchildren)
47 err_quit("no available children");
48 cptr[i].child_status = 1; /* отмечаем этот дочерний процесс как
занятый */
49 cptr[i].child_count++;
50 navail--;
51 n = Write_fd(cptr[i].child_pipefd, 1, connfd);
52 Close(connfd);
53 if (--nsel == 0)
54 continue; /* с результатами select закончено */
55 }
56 /* поиск освободившихся дочерних процессов */
57 for (i = 0; i < nchildren; i++) {
58 if (FD_ISSET(cptr[i].child_pipefd, &rset)) {
59 if ((n = Read(cptr[i].child_pipefd, &rc, 1)) == 0)
60 err_quit("child %d terminated unexpectedly", i);
61 cptr[i].child_status = 0;
62 navail++;
63 if (--nsel == 0)
64 break; /* с результатами select закончено */
Поделиться:
Популярные книги
Газлайтер. Том 8
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
На Ларэде
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
Охота на попаданку. Бракованная жена
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Кай из рода красных драконов
1. Красная кость
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Хозяйка Проклятой Пустоши. Книга 2
2. Хозяйка Проклятой Пустоши
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Безумный Макс. Поручик Империи
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Потусторонний. Книга 2
2. Господин Артемьев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Чапаев и пустота
Проза:
современная проза
8.39
рейтинг книги
Солнечный корт
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Лютая
Любовные романы:
любовно-фантастические романы
6.40
рейтинг книги
Ведьмак (большой сборник)
Ведьмак
Фантастика:
фэнтези
9.29
рейтинг книги
Наследие Маозари 4
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ученик
1. Тай Фун
Фантастика:
фэнтези
5.00
рейтинг книги
Начальник милиции. Книга 5
5. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00