Книга: UNIX: разработка сетевых приложений
Пример: сервер времени и даты, активизированный демоном inetd
Пример: сервер времени и даты, активизированный демоном 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), "%.24srn", 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
с нулевым дескриптором в качестве первого аргумента.
Чтобы выполнить этот пример в нашей системе Solaris, сначала мы присваиваем службе имя и порт, добавляя следующую строку в /etc/services
:
mydaytime 9999/tcp
Затем добавляем строку в /etc/inetd.conf
:
mydaytime stream tcp nowait andy
/home/andy/daytimetcpsrv3 daytimetcpsrv3
(Мы разбили длинную строку на более короткие.) Мы помещаем выполняемый код в заданный файл и отправляем демону inetd
сигнал SIGHUP
, сообщающий ему, что нужно заново считать файл конфигурации. Следующий шаг — выполнить программу netstat
, чтобы проверить, что на порте TCP 9999 создан прослушиваемый сокет:
solaris % netstat -na | grep 9999
*.9999 *.* 0 0 49152 0 LISTEN
Затем мы запускаем сервер с другого узла:
linux % telnet solaris 9999
Trying 192.168.1.20...
Connected to solaris.
Escape character is '^]'.
Tue Jun 10 11:04:02 2003
Connection closed by foreign host.
Файл /var/amd/messages
(в который, как указано в нашем файле /etc/syslog.conf
, должны направляться наши сообщения с аргументом facility=LOG_USER
) содержит запись:
Jun 10 11:04:02 solaris daytimetcpsrv3[28724]: connection from 192.168.1.10.58145
- 13.6. Функция daemon_inetd
- Запуск InterBase-сервера
- Расширенная установка InterBase-сервера
- Пример установочного скрипта
- Пример из практики
- Совместимость клиентов и серверов различных версий
- Статистика InterBase-сервера
- Сервер для InterBase
- 1.3.3. Достоинства и недостатки анонимных прокси-серверов
- Минимальный состав сервера InterBase SuperServer
- ПРИМЕР ПРОСТОЙ ПРОГРАММЫ НА ЯЗЫКЕ СИ
- Отличительные особенности сервера Yaffil