next up previous contents
Next: Серверная часть. Up: Упрощенный интерфейс RPC. Previous: Пример rusers.c.   Contents

Клиентская часть.

Клиентская часть (рис. 35) состоит из вызова функции rpc_call(). Синтаксис функции приведен ниже:

int rpc_call (char *host /* Имя сервера */,

     u_long prognum /* Номер программы сервера */,

     u_long versnum /* Номер версии сервера */,

     xdrproc_t inproc /* фильтр XDR для кодирования arg */,

     char *in /* Указатель на аргументы */,

     xdr_proc_t outproc /* Фильтр декодирования результата */,

     char *out /* Адрес сохранения результата */,

     char *nettype /* Выбор транспортной службы */);

Эта функция вызывает процедуру, указанную prognum, versnum, и procnum на нужном компьютере, указанном host. Аргументы, передаваемые удаленной процедуре, указывают параметром in, а inproc указывает фильтр XDR, чтобы закодировать эти аргументы. Параметр out - это адрес, куда помещается результат удаленной процедуры. outproc представляет фильтр XDR, который расшифрует результат и разместит его по этому адресу.

Клиент блокируется вызовом rpc_call() до тех пор, пока он не получит ответ от сервера. Если сервер отвечает, то возвращается RPC_SUCCESS со значением 0. Если запрос был неудачен, возвращается значение, отличное от 0. Это значение можно преобразовать к типу clnt_stat, перечислимому типу, определенному в файле RPC (<rpc/rpc.h>) и интерпретируемому функцией clnt_sperrno(). Эта функция возвращает указатель на стандартное сообщение RPC об ошибке, соответствующее коду ошибки. В примере испытываются все "видимые" транспортные службы, внесенные в /etc/netconfig. Настройка количества повторов требует использования более низких уровней библиотеки RPC. Множественные аргументы и результаты обрабатываются с помощью объединения их в структуры.

#include <stdio.h>

#include <utmp.h> 

#include <rpc/rpc.h>

#include <rpcsvc/rusers.h>

 

/* программа вызывает удаленную программу RUSERSPROG */

 

main(int argc, char **argv)

{

  unsigned long nusers;

  enum clnt_stat cs;

  if (argc != 2) {

    fprintf(stderr, "Использование: rusers hostname\n");

    exit(1);

  }

  if( cs = rpc_call(argv[1], RUSERSPROG,

      RUSERSVERS, RUSERSPROC_NUM, xdr_void,

      (char *)0, xdr_u_long, (char *)&nusers,

      "visible") != RPC_SUCCESS ) {

         clnt_perrno(cs);

         exit(1);

  }

  fprintf(stderr, "%d пользователей на компьютере %s\n", nusers,

    argv[1] );

  exit(0);

}

Рис. 35. Клиентская часть приложения.

Так как типы данных могут быть представлены различным образом на различных машинах, rpc_call() нужно указать и тип аргумента, и указатель на него (аналогично и для результата). Возвращаемое значение для RUSERSPROC_NUM - unsigned long, поэтому первым возвращаемым параметром rpc_call() будет xdr_u_long, а вторым - *nusers. Поскольку RUSERSPROC_NUM не имеет аргументов, функцией шифрования XDR для rpc_call() будет xdr_void(), а ее аргумент имеет значение NULL.



2003-12-09