単純インタフェースのクライアント側には、 rpc_call() という関数が 1 つだけあります。次の 9 個のパラメータがあります。
int 0 or error code rpc_call ( char *host /* サーバーホストの名前 */ rpcprog_t prognum /* サーバープログラム番号 */ rpcvers_t versnum /* サーバーバージョン番号 */ rpcproc_t procnum /* サーバー手続き番号 */ xdrproc_t inproc /* 引数を符号化する XDR フィルタ */ char *in /* 引数へのポインタ */ xdr_proc_t outproc /* 結果を復号化するフィルタ */ char *out /* 結果を格納するアドレス */ char *nettype /* トランスポートの選択 */ ); |
関数 rpc_call() は、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 を変更したものです。
#include <stdio.h> #include <utmpx.h> #include <rpc/rpc.h> #include <rpcsvc/rusers.h> /* *RUSERSPROG RPC プログラムを呼び出すプログラム */ main(argc, argv) int argc; char **argv; { unsigned int 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_int, (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 int 型であるため、rpc_call() の最初の戻りパラメータは xdr_u_int (unsigned int 用) で、2 番目は &nusers (unsigned int 型の値があるメモリーへのポインタ) です。RUSERSPROC_NUM には引数がないため、rpc_call() の XDR 符号化関数は xdr_void() で、その引数は NULL です。