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-18main19-20child_makeКод обработчика сигнала
SIGINTЛистинг 30.7. Обработчик сигнала SIGINT
//server/serv02.c25 void26 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-34getrusagepr_cpu_timeSIGTERMwaitВ листинге 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-9forkchild_mainЛистинг 30.9. Функция child_main: бесконечный цикл, выполняемый каждым дочерним процессом
//server/child02.c11 void12 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-25acceptweb_childРеализация 4.4BSD
Если вы никогда ранее не сталкивались с таким типом устройства сервера (несколько процессов, вызывающих функцию
acceptРодитель сначала создает прослушиваемый сокет, а затем — дочерние процессы. Напомним, что каждый раз при вызове функции
forkprocfilesocket
Рис. 30.2. Организация структур proc, file и socket
