Для написания сетевой службы в Linux не обязательно уметь программировать сокеты. Сокет, с точки зрения прикладной программы, выглядит как обычный файловый дескриптор, из которого можно читать и в который можно писать любыми стандартными функциями ввода/вывода. Поэтому появляется возможность перенаправить стандартный ввод/вывод любой программы в заранее подготовленный сокет. Для такого перенаправления служит программа xinetd
.
Конфигурация xinetd
, как правило, разделяется на две части: значения по умолчанию – /etc/xinetd.conf
и настройки для отдельных служб, по одному файлу в каталоге /etc/xinetd.d/
на службу.
Чтобы запустить свою сетевую службу, необходимо создать ещё один файл в /etc/xinetd.d/
. Имя файла особого значения не имеет, но обычно выбирается по имени службы. Предположим, что служба называется mynetd
, запускается от имени пользователя user1
и выполняет команду sleep 10
. Служба должна ожидать TCP соединение на порту 8888
.
Конфигурационный файл /etc/xinetd.d/mynetd
будет выглядеть так:
service mynetd
{
disable = no
# Если не написать UNLISTED, то xinetd будет искать имя службы и номер порта
# в файле /etc/services
type = UNLISTED
# stream = TCP, datagram = UDP
socket_type = stream
port = 8888
# Можно считать, что для протокола TCP wait всегда равен 'no',
# а для протокола UDP – всегда 'yes'
wait = no
user = user1
# При считывании конфигурации файл службы должен существовать и заданный пользователь
# должен иметь право на его выполнение
server = /bin/sleep
server_args = 10
}
Параметр wait
интерпретируется следующим образом: если socket_type = datagram
и wait = yes
, то при появлении на порту данных стартует новый процесс со входом/выходом, перенаправленным в сокет. Пока этот процесс не завершится, xinetd
не контролирует наличие новых данных на порту, оставляя их запущенной программе. Если поставить wait = no
, то на каждую дейтаграмму будет запускаться новый процесс, разделяющий со своими предшественниками общий сокет. В такой ситуации невозможно предсказать, какой копии программы достанутся входные данные из сокета. В принципе, такой подход возможен, если обработка дейтаграммы идёт долго, а писать многопоточный сервис лень. Для TCP ситуация обратная, wait = yes
имеет смысл только для многопоточных программ, иначе первый процесс захватит сокет и не отдаст его, пока программа не завершится.