UNIX: взаимодействие процессов
Шрифт:
Сервер и клиент работают следующим образом:
1. При переходе системы в многопользовательский режим запускается пpoгрaммa отображения портов. Исполняемый файл этого демона обычно называется portmap или rpcbind.
2. При запуске сервера его функция main, являющаяся частью заглушки сервера, создаваемой rpcgen, вызывает библиотечную функцию svc_create. Эта функция выясняет, какие сетевые протоколы поддерживаются узлом, и создает конечную точку (например, сокет) для каждого протокола, связывая временные порты с конечными точками протоколов TCP и UDP. Затем она связывается с локальной пpoгрaммoй отображения портов для регистрации временных номеров портов TCP и UDP вместе с номером программы и номером версии.
Сама программа отображения портов
Можно получить список всех пpoгрaмм RPC, зарегистрированных в пpoгрaм-ме отображения портов, запустив пpoгрaммy rpcinfo. Мы можем запустить эту программу, чтобы убедиться, что порт с номером 111 используется самой программой отображения портов:
(Мы исключили множество несущественных в данный момент строк вывода.) Мы видим, что Solaris 2.6 поддерживает все три версии протокола, все на порте 111, причем как TCP, так и UDP. Соответствие номеров пpoгрaмм RPC их именам обычно устанавливается в файле /etc/rpc. Запустив ту же программу в BSD/OS 3.1, увидим, что в этой системе поддерживается только вторая версия программы отображения портов:
В Digital Unix 4.0В также поддерживается только вторая версия:
Затем процесс сервера приостанавливает работу, ожидая поступления запросов от клиентов. Это может быть новое соединение TCP или приход дей-тaгрaммы UDP в порт UDP. Если мы запустим rpcinfo после запуска сервера из листинга 16.3, мы увидим следующий результат:
где 824377344 соответствует 0x31230000 (номер пpoгрaммы, присвоенный ей в листинге 16.1). В том же листинге мы присвоили программе номер версии 1. Обратите внимание, что сервер готов принимать запросы от клиентов по протоколам TCP и UDP и клиент может выбирать, какой из этих протоколов он будет использовать при создании дескриптора клиента (последний аргумент clnt_create в листинге 16.2).
3. Клиент запускается и вызывает clnt_create. Аргументами (листинг 16.2) являются имя узла или IP-адрес сервера, номер пpoгрaммы, номер версии и строка, указывающая протокол связи. Запрос RPC направляется пpoгрaммe отображения портов узла сервера (для этого сообщения обычно используется протокол UDP), причем запрашивается информация об указанной версии указанной программы с указанным протоколом. В случае успеха номер порта сохраняется в дескрипторе клиента для обработки всех последующих вызовов RPC через этот дескриптор.
В листинге 16.1
мы присвоили нашей программе номер 0x31230000. 32-разрядные номера пpoгрaмм подразделяются на группы, приведенные в табл. 16.1.Таблица 16.1. Диапазоны номеров программ для Sun RPC
Номер программы | Описание |
---|---|
0x00000000–0x1fffffff | Определена Sun |
0x20000000–0x3fffffff | Определена пользователем |
0x40000000–0x5fffffff | Временная (для приложений, написанных заказчиком) |
0x60000000–0xffffffff | Зарезервированы |
Пpoгрaммa rpcinfо выводит список программ, зарегистрированных в системе. Другим источником информации о пpoгрaммax RPC могут являться файлы с расширением .х в каталоге /usr/inciude/rpcsvc.
Inetd и серверы RPC
По умолчанию серверы, созданные с помощью rpcgen, могут вызываться сервером верхнего уровня inetd. Этот сервер описывается в разделе 12.5 [24]. Изучение содержимого заглушки сервера, создаваемой rpcgen, показывает, что при запуске функции main сервера она проверяет, является ли стандартный поток ввода конечной точкой XTI, и если так, то предполагается, что сервер был запущен демоном inetd.
После создания сервера RPC, который будет вызываться inetd, следует добавить информацию об этом сервере в файл /etc/inetd.conf. Туда помещаются следующие данные: имя программы RPC, поддерживаемые номера программ, протоколы и полное имя исполняемого файла сервера. В качестве примера мы приводим строку из конфигурационного файла Solaris:
Первое поле содержит имя пpoгрaммы (которому будет сопоставлен номер с помощью файла /etc/rpc); поддерживаются версии 2, 3 и 4. Следующее поле задает конечную точку XTI (или сокет), третье поле говорит о том, что поддерживаются все протоколы видимых дeйтaгрaмм. Если свериться с содержимым файла /etc/netconfig, мы узнаем, что таких протоколов два: UDP и /dev/clts. Глава 29 [24] описывает этот файл и адреса XTI. Четвертое поле (wait) указывает демону inetd на необходимость ожидания завершения этого сервера перед включением режима ожидания запроса клиента для конечной точки XTI. Все серверы RPC указывают атрибут wait в конфигурационном файле /etc/inetd.conf.
Следующее поле, root, указывает идентификатор пользователя, с которым будет выполняться пpoгрaммa. Последние два поля задают полное имя исполняемого файла пpoгрaммы и имя пpoгрaммы вместе с необходимыми аргументами командной строки (у данной пpoгрaммы они отсутствуют).
Демон inetd создаст конечные точки XTI и зарегистрирует их в программе отображения портов для соответствующих номеров пpoгрaмм и версий. Мы можем убедиться в этом с помощью rpcinfo:
Четвертое поле содержит адреса XTI, причем 128×256+11 = 32779, и данное значение является временным номером порта, присвоенным этой концевой точке UDP.