単純インタフェースのクライアント側には、rpc_call() という関数が 1 つだけあります。次の 9 個のパラメタがあります。
int 0 or error code rpc_call ( char *host /* サーバホストの名前 */ u_long prognum /* サーバプログラム番号 */ u_long versnum /* サーババージョン番号 */ xdrproc_t inproc /* 引数を符号化する XDR フィルタ */ char *in /* 引数へのポインタ */ xdr_proc_t outproc /* 結果を復号化するフィルタ */ char *out /* 結果を格納するアドレス */ char *nettype /* トランスポートの選択 */ );
この関数は、host 上で、prognum、versum、procnum によって指定する手続きを呼び出します。遠隔手続きに渡される引数は、in パラメタによって指定され、inproc はこの引数を符号化するための XDR フィルタです。out パラメタは、遠隔手続きから戻される結果が置かれるアドレスです。outproc は、結果を復号化してこのアドレスに置く XDR フィルタです。
クライアントプログラムは、サーバから応答を得るまで rpc_call() のところで停止します。サーバが呼び出しを受け入れると、0 の値で RPC_SUCCESS を返します。呼び出しが失敗した場合は、0 以外の値が返されます。この値は、clnt_stat
で指定される型に型変換されます。これは RPC インクルードファイルの中で定義される列挙型で、clnt_sperrno() 関数により解釈されます。この関数は、このエラーコードに対応する標準 RPC エラーメッセージへのポインタを返します。
この例では、/etc/netconfig に列挙されているすべての選択可能な可視トランスポートが試されます。試行回数を指定するには、下位レベルの RPC ライブラリを使用する必要があります。
複数の引数と複数の結果は、構造体に収集して扱われます。
例 4-1 を単純インタフェースを使用するために変更すると、例 4-2 のようになります。
#include <stdio.h> #include <utmp.h> #include <rpc/rpc.h> #include <rpcsvc/rusers.h> /* *RUSERSPROG RPC プログラムを呼び出すプログラム */ main(argc, argv) int argc; char **argv; { unsigned long nusers; enum clnt_stat cs; if (argc != 2) { fprintf(stderr, "usage: 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 users on %s¥n", nusers, argv[1] ); exit(0); }
マシンが異なれば、データ型も異なる表現になるため、rpc_call() は RPC 引数の型と RPC
引数へのポインタを必要とします (サーバから返される結果についても同様です)。RUSERSPROC_NUM の場合、戻り値は unsigned
long
型であるため、rpc_call() の最初の戻りパラメタは xdr_u_long (unsigned
long
用) で、2 番目は &nusers (unsigned
long
型の値があるメモリへのポインタ)です。RUSERSPROC_NUM には引数がないため、rpc_call() の XDR 符号化関数は xdr_void() で、その引数は NULL です。