Чтение онлайн

на главную

Жанры

UNIX: разработка сетевых приложений
Шрифт:

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), "%.24s\r\n", ctime(&ticks));

25 Write(connfd, buff, strlen(buff));

26 Close(connfd);

27 }

28 }

Изменений

всего два: мы вызываем нашу функцию
daemon_init
, как только программа запускается, а затем вызываем нашу функцию
err_msg
вместо
printf
, чтобы вывести IP-адрес и порт клиента. На самом деле, если мы хотим, чтобы наши программы могли выполняться как демоны, мы должны исключить вызов функций
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
заранее известного порта с сокетом, ожидание соединения (TCP) или получения дейтаграммы (UDP) и последующее выполнение функции
fork
. Дочерний процесс выполнял обслуживание клиента, а родительский процесс ждал, когда поступит следующий запрос клиента. Эта модель характеризуется двумя недостатками.

1. Все демоны содержали практически идентичный код запуска, направленный сначала на создание сокета, а затем на превращение процесса в процесс демона (аналогично нашей функции

daemon_init
).

2. Каждый демон занимал некоторое место в таблице процессов, но при этом большую часть времени находился в состоянии ожидания.

Реализация 4.3BSD упростила ситуацию, предоставив суперсервер( superserver) Интернета — демон

inetd
. Этот демон может применяться серверами, использующими TCP или UDP, и не поддерживает других протоколов, таких как доменные сокеты Unix.
Демон
inetd
решает две вышеупомянутые проблемы.

1. Он упрощает написание процессов демонов, поскольку обрабатывает большинство подробностей запуска. Таким образом устраняется необходимость вызова нашей функции

daemon_init
для каждого сервера.

2. Этот демон позволяет одиночному процессу (

inetd
) ждать входящие клиентские запросы ко множеству служб (вместо одного процесса для каждой службы). Это сокращает общее число процессов в системе.

Процесс

inetd
сам становится демоном, используя технологии, которые мы изложили при описании функции
daemon_init
. Затем он считывает и обрабатывает файл конфигурации, обычно файл
/etc/inetd.conf
. Этот файл задает, какие службы должен обрабатывать суперсервер, а также что нужно делать, когда приходит запрос к одной из этих служб. Каждая строка содержит поля, показанные в табл. 13.4. Вот несколько строк в качестве примера:

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
ПРИМЕЧАНИЕ

Таблица и приведенные строки — это только пример. Большинство производителей добавили демону inetd свои собственные функции. Примером может служить возможность обрабатывать серверы вызовов удаленных процедур (RPC) в дополнение к серверам TCP и UDP, а также возможность обрабатывать другие протоколы, отличные от TCP и UDP. Полное имя для функции exec и аргументы командной строки сервера, очевидно, зависят от приложения.

Флаг wait-flag может быть достаточно труден для понимания. Он указывает, собирается ли демон, запускаемый inetd, взять на себя работу с прослушиваемым сокетом. Сервисы UDP лишены деления на прослушиваемые и принятые сокеты, и потому практически всегда создаются с флагом wait-flag, равным wait. Сервисы TCP могут вести себя по-разному, но чаще всего для них указывается флаг wait-flag со значением nowait.

Взаимодействие IPv6 с файлом /etc/inetd.conf зависит от производителя. Иногда в качестве поля protocol указывается tcp6 или udp6, чтобы подчеркнуть, что для сервера должен быть создан сокет IPv6. Некоторые разрешают использовать значения protocol, равные tcp46 и udp46, если сервер готов принимать соединения по обоим протоколам. Специальные названия протоколов обычно не включаются в файл /etc/protocols.

Поделиться:
Популярные книги

Заход. Солнцев. Книга XII

Скабер Артемий
12. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Заход. Солнцев. Книга XII

Случайная свадьба (+ Бонус)

Тоцка Тала
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Случайная свадьба (+ Бонус)

Приручитель женщин-монстров. Том 3

Дорничев Дмитрий
3. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 3

Ищу жену для своего мужа

Кат Зозо
Любовные романы:
любовно-фантастические романы
6.17
рейтинг книги
Ищу жену для своего мужа

Сердце Дракона. Том 19. Часть 1

Клеванский Кирилл Сергеевич
19. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.52
рейтинг книги
Сердце Дракона. Том 19. Часть 1

Пустоцвет

Зика Натаэль
Любовные романы:
современные любовные романы
7.73
рейтинг книги
Пустоцвет

Жребий некроманта. Надежда рода

Решетов Евгений Валерьевич
1. Жребий некроманта
Фантастика:
фэнтези
попаданцы
6.50
рейтинг книги
Жребий некроманта. Надежда рода

Возвышение Меркурия. Книга 4

Кронос Александр
4. Меркурий
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Возвышение Меркурия. Книга 4

Бездомыш. Предземье

Рымин Андрей Олегович
3. К Вершине
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Бездомыш. Предземье

Столичный доктор. Том II

Вязовский Алексей
2. Столичный доктор
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Столичный доктор. Том II

Последний из рода Демидовых

Ветров Борис
Фантастика:
детективная фантастика
попаданцы
аниме
5.00
рейтинг книги
Последний из рода Демидовых

Камень. Книга восьмая

Минин Станислав
8. Камень
Фантастика:
фэнтези
боевая фантастика
7.00
рейтинг книги
Камень. Книга восьмая

Измена. Не прощу

Леманн Анастасия
1. Измены
Любовные романы:
современные любовные романы
4.00
рейтинг книги
Измена. Не прощу

Измена. Верну тебя, жена

Дали Мила
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Верну тебя, жена