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 else
17 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_init
err_msg
printf
printf
fprintf
err_msg
Обратите внимание, что мы проверяем argc и выводим соответствующее сообщение до вызова
daemon_init
daemon_init
Если мы запустим эту программу на нашем узле
linux
/var/log/messages
LOG_USER
Jul 10 09:54:37 linux daytimetcpsrv2[24288]: connection from 127.0.0.1.55862
Дата, время и имя узла автоматически ставятся в начале сообщения демоном
syslogd
13.5. Демон inetd
В типичной системе Unix может существовать много серверов, ожидающих запроса клиента. Примерами являются FTP, Telnet, Rlogin, TFTP и т.д. В системах, предшествующих 4.3BSD, каждая из этих служб имела связанный с ней процесс. Этот процесс запускался во время загрузки из файла
/etc/rc
bind
fork
1. Все демоны содержали практически идентичный код запуска, направленный сначала на создание сокета, а затем на превращение процесса в процесс демона (аналогично нашей функции
daemon_init
2. Каждый демон занимал некоторое место в таблице процессов, но при этом большую часть времени находился в состоянии ожидания.
Реализация 4.3BSD упростила ситуацию, предоставив суперсервер (superserver) Интернета — демон
inetd
inetd
1. Он упрощает написание процессов демонов, поскольку обрабатывает большинство подробностей запуска. Таким образом устраняется необходимость вызова нашей функции
daemon_init
2. Этот демон позволяет одиночному процессу (
inetd
Процесс
inetd
daemon_init
/etc/inetd.conf
ftp stream tcp nowait root /usr/bin/ftpd ftpd -l
telnet stream tcp nowait root /usr/bin/telnetd telnetd
login stream tcp nowait root /usr/bin/rlogind rlogind -s
tftp 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 |