Сеть TCP/IP в Linux
Обслуживание прикладного уровня в Linux
Самый простой способ проверить, предоставляет ли некий сервер услуги по некоему TCP-порту – это подключиться к нему. Если под рукой нет приложения, работающего по соответствующему протоколу, не беда: подойдет утилита telnet. В качестве первого параметра следует указать адрес компьютера, к которому нужно подключиться, а в качестве второго (необязательного) – номер порта. Когда-то эта утилита использовалась в качестве клиента к терминальной службе, однако от нее пришлось отказаться: пароль пользователя передавался по сети незашифрованным. Но в качестве клиента других служб, многие из которых используют текстовые протоколы, telnet используется и поныне. Если даже протокол не текстовый, можно выйти в командный режим telnet, нажав "^[", и подать команду close, которая закроет соединение:
[root@localhost root]# telnet 192.168.102.1 112 Trying 192.168.102.1... telnet: connect to address 192.168.102.1: Connection refused [root@localhost root]# telnet 192.168.102.1 111 Trying 192.168.102.1... Connected to 192.168.102.1. Escape character is '^]'. ^[ telnet> close Connection closed.Пример 14.8. Использование telnet
В сценариях вместо интерактивной утилиты telnet стоит использовать netcat, которая работает как cat в указанный сокет или из него. Как уже говорилось, интерпретацией прикладных протоколов занимаются разнообразные программы. Прикладной протокол можно представить как обмен сообщениями, часто текстовыми, между клиентом и сервером. Было бы естественно оформлять такие программы в виде фильтров, чтобы пользоваться простейшими функциями ввода-вывода. Однако механизм сокетов предусматривает асинхронную передачу данных, для чего используются другие функции. Программа, желающая обслуживать сетевые соединения по определенному порту, должна удовлетворять четырем требованиям:
- Быть демоном, то есть постоянно находиться в памяти;
- Создавать сокет, прикреплять его к порту ;
- Регистрироваться как обработчик по этому сокету и принимать соединения (возможно, придется обрабатывать несколько соединений одновременно);
- Анализировать прикладной протокол и действовать по результатам анализа.
Нетрудно заметить, что первые три свойства – общие для большинства сервисов. В Linux есть метадемон inetd, который берет на себя всю общую сетевую часть работы, а программам предоставляет разбираться в прикладном протоколе. Организовать свой сетевой сервис с помощью inetd становится очень просто: пользователь программирует фильтр, задача которого – обмениваться командами прикладного протокола с помощью стандартного ввода и стандартного вывода. Этот фильтр регистрируется в настройках inetd с указанием порта, с которого будут приниматься запросы. После чего сам inetd становится обработчиком запросов по всем указанным портам, сам открывает соединение, запуская соответствующий фильтр, а данные из сокета пересылает туда и обратно по двум каналам. При этом фильтр-обработчик даже не должен быть демоном: это обычная программа, которая завершается, когда это предусмотрено прикладным протоколом, или когда закрывается входной поток.
Мефодий минут за пять написал службу, которая в ответ на подключение передает календарь на текущий месяц. В его системе используется модернизированная версия inetd – xinetd, обученная чтению конфигурационных файлов по схеме ".d":
[root@localhost root]# grep quake /etc/services quake 26000/tcp quake 26000/udp [root@localhost root]# cat /etc/xinetd.d/calendar service quake { socket_type = stream protocol = tcp wait = no user = nobody server = /usr/bin/cal disable = no }Пример 14.9. Настройка cal в качестве сетевой службы
Вместо номера порта можно использовать название протокола из /etc/services. Мефодий воспользовался портом 26000 (чем мог создать некоторые трудности любителям одной компьютерной игры). Осталось только перезагрузить xinetd, чтобы он нашел новый конфигурационный файл, и подключиться к порту 26000:
[root@localhost root]# service xinetd restart Stopping xinetd service: [ DONE ] Starting xinetd service: [ DONE ] [root@localhost root]# telnet localhost quake Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. December 2004 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31Пример 14.10. Подключение к самодельной службе "календарь"