Программа сервера, использующая упрощенный интерфейс, достаточно простая
(рис. 36). Она вызывает rpc_reg(), чтобы зарегистрировать
процедуру, которая будет вызвана, а затем вызывает svc_run(),
диспетчера удаленных процедур библиотеки RPC, который ждет входящих
запросов.
Прототип rpc_reg():
int rpc_reg(u_long prognum /* Номер программы сервера */,
u_long versnum /* Номер версии сервера */,
u_long procnum /* Номер процедуры сервера */,
char *procname /* Имя удаленной функции */,
xdrproc_t inproc /* Фильтр для кодирования аргумента arg */,
svc_run() вызывает сервисные процедуры в ответ на вызовы
RPC. Диспетчер в rpc_reg() заботится о расшифровывании аргументов
удаленных процедур, и о зашифровывании результатов, с использованием
фильтров XDR, определенных при регистрации удаленной процедуры.
Некоторые замечания относительно программы сервера:
Большинство приложений RPC используют при именовании добавления в
конец имени функции _1. Строка _n добавляется к именам
процедур, чтобы указать номер версии n некоторого сервиса.
Аргумент и результат передаются через адреса. Это справедливо для
всех функций, которые вызываются удаленно. Если Вы передаете NULL
в качестве результата функции, то клиенту не посылается никакого ответа.
Предполагается, что ответа для пересылки нет.
Результат должен располагаться в статической памяти, поскольку к нему
обращаются после того, как процедура завершилась. Функция библиотеки
RPC, которая создает ответное сообщение RPC, получает доступ к результату
и посылает значения клиенту.
Допускается только один аргумент. Если нужно передавать несколько
элементов данных, они должны быть объединены в структуру, которую
можно передать как единую информационную конструкцию.
Процедура регистрируется для каждой транспортной службы указанного
типа. Если параметр типа - (char*)NULL, процедура регистрируется
для всех типов служб, указанных в NETPATH.
Иногда программа, написанная вручную, более компактна, чем созданная
с помощью rpcgen. Ниже приведен пример процедуры регистрации.
Он регистрирует единственную процедуру и вызывает svc_run(),
чтобы обслуживать запросы.
#include <stdio.h>
#include <rpc/rpc.h>
#include <rpcsvc/rusers.h>
void *rusers();
main()
{
if(rpc_reg(RUSERSPROG, RUSERSVERS,
RUSERSPROC_NUM, rusers,
xdr_void, xdr_u_long,
"visible") == -1) {
fprintf(stderr, "Невозможно зарегистрировать\n");
exit(1);
}
svc_run(); /* Процедура без возврата */
fprintf(stderr, "Ошибка: Выход из svc_run!\n");
exit(1);
}
Рис. 36. Серверная часть приложения.
rpc_reg() можно вызвать сколько угодно раз, чтобы зарегистрировать
все различные программы, версии, и процедуры.