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

на главную

Жанры

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

Причина, по которой дейтаграммный сервер должен завладевать сокетом, пока он не завершит работу, лишая тем самым демон

inetd
возможности выполнять функцию
select
на этом сокете для проверки готовности его для чтения (в ожидании другой дейтаграммы клиента), в том, что для сервера дейтаграмм существует только один сокет, в отличие от сервера TCP, у которого имеется прослушиваемый сокет и по одному присоединенному сокету для каждого клиента. Если демон
inetd
не отключил чтение на сокете дейтаграмм и, допустим, родительский процесс (
inetd
) завершил выполнение перед дочерним, дейтаграмма
от клиента все еще будет находиться в приемном буфере сокета. Это приводит к тому, что функция
select
снова сообщает, что сокет готов для чтения, и демон
inetd
снова выполняет функцию
fork
, порождая другой (ненужный) дочерний процесс. Демон
inetd
должен игнорировать дейтаграммный сокет до тех пор, пока он не узнает, что дочерний процесс прочитал дейтаграмму из приемного буфера сокета. Демон
inetd
узнает, что дочерний процесс закончил работу с сокетом, путем получения сигнала
SIGCHLD
, указывающего на то, что дочерний процесс завершился. Подобный пример мы показываем в разделе 22.7.

Пять стандартных служб Интернета, описанных в табл. 2.1, обеспечиваются самим демоном

inetd
(см. упражнение 13.2).

Поскольку функцию

accept
для сервера TCP вызывает демон
inetd
(а не сам сервер), реальный сервер, запускаемый демоном
inetd
, обычно вызывает функцию
getpeername
для получения IP-адреса и номера порта клиента. Вспомните рис. 4.9, где мы показывали, что после выполнения вызовов
fork
и
exec
(что выполняет демон
inetd
) у реального сервера есть единственный способ получить идентификацию клиента — вызвать функцию
getpeername
.

Демон

inetd
обычно не используется для серверов, работающих с большими объемами данных, в особенности почтовыми серверами и веб-серверами. Например, функция
sendmail
обычно запускается как стандартный параллельный сервер, как мы отмечали в разделе 4.8. В этом режиме стоимость порождения процесса для каждого клиентского соединения равна стоимости функции
fork
, тогда как в случае сервера TCP, активизированного демоном
inetd
, — стоимости функций
fork
и
exec
. Веб-серверы используют множество технологий для минимизации накладных расходов при порождении процессов для обслуживания клиентов, как мы покажем в главе 30.

13.6. Функция daemon_inetd

В листинге 13.3 показана функция

daemon_inetd
, которую мы можем вызвать с сервера, запущенного демоном
inetd
.

Листинг 13.3. Функция daemon_inetd для придания свойств демона процессу, запущенному демоном inetd

//daemon_inetd.c

1 #include "unp.h"

2 #include <syslog.h>

3 extern int daemon_proc; /* определено в error.c */

4 void

5 daemon_inetd(const char *pname, int facility)

6 {

7 daemon_proc = 1; /* для наших функций err_XXX */

8 openlog(pname, LOG_PID, facility);

9 }

Эта

функция тривиальна по сравнению с
daemon_init
, потому что все шаги выполняются демоном
inetd
при запуске. Все, что мы делаем, — устанавливаем флаг
daemon_proc
для наших функций ошибок (см. табл. Г.1) и вызываем функцию
openlog
с теми же аргументами, что и при вызове функции
daemon_init
, представленной в листинге 13.1.

Пример: сервер времени и даты, активизированный демоном inetd

Листинг 13.4 представляет собой модификацию нашего сервера времени и даты, показанного в листинге 13.2, который может быть активизирован демоном

inetd
.

Листинг 13.4. Не зависящий от протокола сервер времени и даты, который может быть активизирован демоном inetd

//inetd/daytimetcpsrv3.c

1 #include "unp.h"

2 #include <time.h>

3 int

4 main(int argc, char **argv)

5 {

6 socklen_t len;

7 struct sockaddr *cliaddr;

8 char buff[MAXLINE];

9 time_t ticks;

10 daemon_inetd(argv[0], 0);

11 cliaddr = Malloc(MAXSOCKADDR);

12 len = MAXSOCKADDR;

13 Getpeername(0, cliaddr, &len);

14 err_msg("connection from %s", Sock_ntop(cliaddr, len));

15 ticks = time(NULL);

16 snprintf(buff, sizeof(buff), "%.24s\r\n\", ctime(&ticks));

17 Write(0, buff, strlen(buff));

18 Close(0); /* закрываем соединение TCP */

19 exit(0);

20 }

В программе сделано два важных изменения. Во-первых, исчез весь код создания сокета: вызовы функций

tcp_listen
и
accept
. Эти шаги выполняются демоном
inetd
, и мы ссылаемся на соединение TCP, используя нулевой дескриптор (стандартный поток ввода). Во-вторых, исчез бесконечный цикл
for
, поскольку сервер активизируется по одному разу для каждого клиентского соединения. После предоставления сервиса клиенту сервер завершает свою работу.

Вызов функции getpeername

11-14
Поскольку мы не вызываем функцию
tcp_listen
, мы не знаем размера структуры адреса сокета, которую она возвращает, а поскольку мы не вызываем функцию
accept
, то не знаем и адреса протокола клиента. Следовательно, мы выделяем буфер для структуры адреса сокета, используя нашу константу
MAXSOCKADDR
и вызываем функцию
getpeername
с нулевым дескриптором в качестве первого аргумента.

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

Штурм Земли

Семенов Павел
8. Пробуждение Системы
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Штурм Земли

Чехов. Книга 3

Гоблин (MeXXanik)
3. Адвокат Чехов
Фантастика:
альтернативная история
5.00
рейтинг книги
Чехов. Книга 3

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Последний попаданец 11. Финал. Часть 1

Зубов Константин
11. Последний попаданец
Фантастика:
фэнтези
юмористическое фэнтези
рпг
5.00
рейтинг книги
Последний попаданец 11. Финал. Часть 1

Право налево

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

Комбинация

Ланцов Михаил Алексеевич
2. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Комбинация

Прометей: Неандерталец

Рави Ивар
4. Прометей
Фантастика:
героическая фантастика
альтернативная история
7.88
рейтинг книги
Прометей: Неандерталец

Идеальный мир для Лекаря 16

Сапфир Олег
16. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 16

Двойня для босса. Стерильные чувства

Лесневская Вероника
Любовные романы:
современные любовные романы
6.90
рейтинг книги
Двойня для босса. Стерильные чувства

Деспот

Шагаева Наталья
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Деспот

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

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

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

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

Титан империи 6

Артемов Александр Александрович
6. Титан Империи
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Титан империи 6