UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
В листинге 30.2 показана функция
mainЛистинг 30.2. Функция main для параллельного сервера TCP
//server/serv01.c 1 include "unp.h" 2 int 3 main(int argc, char **argv) 4 { 5 int listenfd, connfd; 6 pid_t childpid; 7 void sig_chld(int), sig_int(int), web_child(int); 8 socklen_t clilen, addrlen; 9 struct sockaddr *cliaddr;10 if (argc == 2)11 listenfd = Tcp_listen(NULL, argv[1], &addrlen);12 else if (argc == 3)13 listenfd = Tcp_listen(argv[1], argv[2], &addrlen);14 else15 err_quit("usage: serv01 [ <host> ] <port#>");16 cliaddr = Malloc(addrlen);17 Signal(SIGCHLD, sig_chld);18 Signal(SIGINT, sig_int);19 for (;;) {20 clilen = addrlen;21 if ((connfd = accept(listenfd, cliaddr, &clilen)) < 0) {22 if (errno == EINTR)23 continue; /* назад к for() */24 else25 err_sys("accept error");26 }27 if ((childpid = Fork()) == 0) { /* дочерний процесс */28 Close(listenfd); /* закрываем прослушиваемый сокет */29 web_child(connfd); /* обрабатываем запрос */30 exit(0);31 }32 Close(connfd); /* родительский процесс закрывает присоединенный сокет */33 }34 }Эта функция аналогична функции, показанной в листинге 5.9: она вызывает функцию
forkSIGCHLDtcp_listensig_chldprintfМы также перехватываем сигнал
SIGINTЛистинг 30.3. Обработчик сигнала SIGINT
//server/serv01.c35 void36 sig_int(int signo)37 {38 void pr_cpu_time(void);39 pr_cpu_time();40 exit(0);41 }В листинге 30.4 показана функция
pr_cpu_timeЛистинг 30.4. Функция pr_cpu_time: вывод полного времени центрального процессора
//server/pr_cpu_time.c 1 #include "unp.h" 2 #include <sys/resource.h> 3 #ifndef HAVE_GETRUSAGE_PROTO 4 int getrusage(int, struct rusage*); 5 #endif 6 void 7 pr_cpu_time(void) 8 { 9 double user, sys;10 struct rusage myusage, childusage;11 if (getrusage(RUSAGE_SELF, &myusage) < 0)12 err_sys("getrusage error");13 if (getrusage(RUSAGE_CHILDREN, &childusage) < 0)14 err_sys("getrusage error");15 user = (double)myusage.ru_utime.tv_sec +16 myusage.ru_utime.tv_usec / 1000000.0;17 user += (double)childusage.ru_utime.tv_sec +18 childusage.ru_utime.tv_usec / 1000000.0;19 sys = (double)myusage.ru_stime.tv_sec +20 myusage.ru_stime.tv_usec / 1000000.0;21 sys += (double)childusage.ru_stime.tv_sec +22 childusage.ru_stime.tv_usec / 1000000.0;21 printf("nuser time = %g, sys time = %gn", user, sys);22 }Функция
getrusageRUSAGE_SELFRUSAGE_CHILDRENВозвращаясь к листингу 30.2, мы видим, что для обработки каждого клиентского запроса вызывается функция
web_child
