単純インタフェースのクライアント側には、 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 です。