Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

он был открыт */

21 child_main(i, listenfd, addrlen); /* никогда не завершается */

22 }

Рис. 30.3. Канал после того, как дочерний и родительский процесс закрыли один конец

После создания всех дочерних процессов мы получаем схему, показанную на рис. 30.4. Мы закрываем прослушиваемый сокет в каждом дочернем процессе, поскольку только родительский процесс вызывает функцию

accept
. Мы показываем на рисунке, что родительский процесс должен обрабатывать прослушиваемый сокет, а также все доменные сокеты. Как можно догадаться, родительский процесс использует функцию
select
для мультиплексирования всех дескрипторов.

Рис. 30.4. Каналы после создания всех дочерних процессов

В листинге 30.18 показана функция

main
. В отличие от предыдущих версий этой функции, в данном случае в памяти размещаются все наборы дескрипторов и в каждом наборе включены все биты, соответствующие прослушиваемому сокету и каналу каждого дочернего процесса. Вычисляется также максимальное значение дескриптора и выделяется память для массива структур
Child
. Основной цикл запускается при вызове функции
select
.

Листинг 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;

  • Читать дальше
  • 1
  • ...
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: