異なるホストでは RPC サーバーの異なるバージョンが実行されている可能性があるので、クライアントはさまざまなバージョンに対応できるようにしなければなりません。たとえば、あるサーバーでは旧バージョン RUSERSPROG(RUSERSVERS_ORIG) が実行されており、別のサーバーでは最新バージョン RUSERSPROG(RUSERSVERS_SHORT) が実行されているとします。
サーバーのバージョンがクライアント作成ルーチン clnt_call() で指定したバージョン番号と一致しない場合は、clnt_call() から RPCPROGVERSMISMATCH というエラーが返されます。サーバーがサポートしているバージョン番号を取り出して、正しいバージョン番号をもつクライアントハンドルを作成することもできます。そのためには、例 4-36 のルーチンを使用するか、clnt_create_vers() を使用します。詳細については、rpc(3NSL) のマニュアルページを参照してください。
main()
{
enum clnt_stat status;
u_short num_s;
u_int num_l;
struct rpc_err rpcerr;
int maxvers, minvers;
CLIENT *clnt;
clnt = clnt_create("remote", RUSERSPROG, RUSERSVERS_SHORT,
"datagram_v");
if (clnt == (CLIENT *) NULL) {
clnt_pcreateerror("unable to create client handle");
exit(1);
}
to.tv_sec = 10; /* タイムアウト値を設定 */
to.tv_usec = 0;
status = clnt_call(clnt, RUSERSPROC_NUM, xdr_void,
(caddr_t) NULL, xdr_u_short,
(caddr_t)&num_s, to);
if (status == RPC_SUCCESS) { /* 最新バージョン番号が見つかった場合 */
printf("num = %d¥n", num_s);
exit(0);
}
if (status != RPC_PROGVERSMISMATCH) { /* その他のエラー */
clnt_perror(clnt, "rusers");
exit(1);
}
/* 指定したバージョンがサポートされていない場合 */
clnt_geterr(clnt, &rpcerr);
maxvers = rpcerr.re_vers.high; /* サポートされている最新バージョン */
minvers = rpcerr.re_vers.low; /* サポートされている最も古いバージョン */
if (RUSERSVERS_SHORT < minvers || RUSERSVERS_SHORT > maxvers)
{
/* サポート範囲内にない場合 */
clnt_perror(clnt, "version mismatch");
exit(1);
}
(void) clnt_control(clnt, CLSET_VERSION, RUSERSVERS_ORIG);
status = clnt_call(clnt, RUSERSPROC_NUM, xdr_void,
(caddr_t) NULL, xdr_u_int, (caddr_t)&num_l, to);
if (status == RPC_SUCCESS)
/* 識別できるバージョン番号が見つかった場合 */
printf("num = %d¥n", num_l);
else {
clnt_perror(clnt, "rusers");
exit(1);
}
}
|