UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Пример: сервер времени и даты в качестве демона
В листинге 13.2 представлено изменение нашего сервера времени и даты, не зависящего от протокола. В отличие от сервера, показанного в листинге 11.8, в нем вызывается функция
daemon_initЛистинг 13.2. Не зависящий от протокола сервер времени и даты, работающий в качестве демона
//inetd/daytimetcpsrv2.c 1 #include "unp.h" 2 #include <time.h> 3 int 4 main(int argc, char **argv) 5 { 6 int listenfd, connfd; 7 socklen_t addrlen, len; 8 struct sockaddr *cliaddr; 9 char buff[MAXLINE];10 time_t ticks;11 daemon_init(argv[0], 0);12 if (argc == 2)13 listenfd = Tcp_listen(NULL, argv[1], &addrlen);14 else if (argc == 3)15 listenfd = Tcp_listen(argv[1], argv[2], &addrlen);16 else17 err_quit("usage: daytimetcpsrv2 [ <host> ] <service or port>");18 cliaddr = Malloc(addrlen);19 for (;;) {20 len = addrlen;21 connfd = Accept(listenfd, cliaddr, &len);22 err_msg("connection from %s", Sock_ntop(cliaddr, len));23 ticks = time(NULL);24 snprintf(buff, sizeof(buff), "%.24srn", ctime(&ticks));25 Write(connfd, buff, strlen(buff));26 Close(connfd);27 }28 }Изменений всего два: мы вызываем нашу функцию
daemon_initerr_msgprintfprintffprintferr_msgОбратите внимание, что мы проверяем argc и выводим соответствующее сообщение до вызова
daemon_initdaemon_initЕсли мы запустим эту программу на нашем узле
linux/var/log/messagesLOG_USERJul 10 09:54:37 linux daytimetcpsrv2[24288]: connection from 127.0.0.1.55862Дата, время и имя узла автоматически ставятся в начале сообщения демоном
syslogd13.5. Демон inetd
В типичной системе Unix может существовать много серверов, ожидающих запроса клиента. Примерами являются FTP, Telnet, Rlogin, TFTP и т.д. В системах, предшествующих 4.3BSD, каждая из этих служб имела связанный с ней процесс. Этот процесс запускался во время загрузки из файла
/etc/rcbindfork1. Все демоны содержали практически идентичный код запуска, направленный сначала на создание сокета, а затем на превращение процесса в процесс демона (аналогично нашей функции
daemon_init2. Каждый демон занимал некоторое место в таблице процессов, но при этом большую часть времени находился в состоянии ожидания.
Реализация 4.3BSD упростила ситуацию, предоставив суперсервер (superserver) Интернета — демон
inetdinetd1. Он упрощает написание процессов демонов, поскольку обрабатывает большинство подробностей запуска. Таким образом устраняется необходимость вызова нашей функции
daemon_init2. Этот демон позволяет одиночному процессу (
inetdПроцесс
inetddaemon_init/etc/inetd.confftp stream tcp nowait root /usr/bin/ftpd ftpd -ltelnet stream tcp nowait root /usr/bin/telnetd telnetdlogin stream tcp nowait root /usr/bin/rlogind rlogind -stftp dgram udp wait nobody /usr/bin/tftpd tftpd -s /tftpbootДействительное имя сервера всегда передается в качестве первого аргумента программе, выполняемой с помощью функции
execТаблица 13.4. Поля файла inetd.conf
| Поле | Описание |
|---|---|
| service-name | Должен быть в /etc/services |
| socket-type | stream (TCP) или dgram (UDP) |
| Protocol | Должен быть в /etc/protocols; либо tcp, либо udp |
| wait-flag | Обычно nowait для TCP и wait для UDP |
| login-name | Из /etc/password; обычно root |
| server-program | Полное имя программы для вызова exec |
| server-program-arguments | Аргументы программы для вызова exec |
