UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
16 err_quit("usage: serv02 [ <host> ] <port#> <#children>");
17 nchildren = atoi(argv[argc - 1]);
18 pids = Calloc(nchildren, sizeof(pid_t));
19 for (i = 0; i < nchildren; i++)
20 pids[i] = child_make(i, listenfd, addrlen); /* возвращение родительского процесса */
21 Signal (SIGINT, sig_int);
22 for (;;)
23 pause(); /* дочерние процессы завершились */
24 }
11-18
main
19-20
child_make
Код обработчика сигнала
SIGINT
Листинг 30.7. Обработчик сигнала SIGINT
//server/serv02.c
25 void
26 sig_int(int signo)
27 {
28 int i;
29 void pr_cpu_time(void);
30 /* завершаем все дочерние процессы */
31 for (i = 0; i < nchildren; i++)
32 kill(pids[i], SIGTERM);
33 while (wait(NULL) > 0) /* ждем завершения всех дочерних процессов */
34 ;
35 if (errno != ECHILD)
36 err_sys("wait error");
37 pr_cpu_time();
38 exit(0);
39 }
30-34
getrusage
pr_cpu_time
SIGTERM
wait
В листинге 30.8 показана функция
child_make
Листинг 30.8. Функция child_make: создание очередного дочернего процесса
//server/child02.c
1 #include "unp.h"
2 pid_t
3 child_make(int i, int listenfd, int addrlen)
4 {
5 pid_t pid;
6 void child_main(int, int, int);
7 if ( (pid = Fork()) > 0)
8 return (pid); /* родительский процесс */
9 child_main(i, listenfd, addrlen); /* никогда не завершается */
10 }
7-9
fork
child_main
Листинг 30.9. Функция child_main: бесконечный цикл, выполняемый каждым дочерним процессом
//server/child02.c
11 void
12 child_main(int i, int listenfd, int addrlen)
13 {
14 int connfd;
15 void web_child(int);
16 socklen_t clilen;
17 struct sockaddr *cliaddr;
18 cliaddr = Malloc(addrlen);
19 printf("child %ld startingn", (long)getpid());
20 for (;;) {
21 clilen = addrlen;
22 connfd = Accept(listenfd, cliaddr, &clilen);
23 web_child(connfd); /* обработка запроса */
24 Close(connfd);
25 }
26 }
20-25
accept
web_child
Реализация 4.4BSD
Если вы никогда ранее не сталкивались с таким типом устройства сервера (несколько процессов, вызывающих функцию
accept
Родитель сначала создает прослушиваемый сокет, а затем — дочерние процессы. Напомним, что каждый раз при вызове функции
fork
proc
file
socket
Рис. 30.2. Организация структур proc, file и socket