アプリケーションで RPC のボトムレベルインタフェースを使用すると、すべてのオプションを使用して通信を制御できます。clnt_tli_create() などのエキスパートレベルの RPC インタフェースは、ボトムレベルのルーチンを使用しています。ユーザーがこのレベルのルーチンを直接使用することはほとんどありません。
ボトムレベルのルーチンは内部データ構造を作成し、バッファを管理し、RPC ヘッダーを作成します。ボトムレベルルーチンの呼び出し側 (エキスパートレベルのルーチンで言えば、clnt_tli_create() ) では、クライアントハンドルの cl_netid と cl_tp の両フィールドを初期化する必要があります。作成したハンドルの cl_netid にはトランスポートのネットワーク ID (たとえば udp) を設定し、cl_tp にはトランスポートのデバイス名 (たとえば /dev/udp) を設定します。clnt_dg_create() と clnt_vc_create() のルーチンは、clnt_ops と cl_private のフィールドを設定します。
次に、clnt_vc_create() と clnt_dg_create() の呼び出し方法を示します。
/*
* 使用する変数 :
* cl: CLIENT *
* tinfo: struct t_info (t_open() または t_getinfo() からの戻り値)
* svcaddr: struct netbuf *
*/
switch(tinfo.servtype) {
case T_COTS:
case T_COTS_ORD:
cl = clnt_vc_create(fd, svcaddr,
prog, vers, sendsz, recvsz);
break;
case T_CLTS:
cl = clnt_dg_create(fd, svcaddr,
prog, vers, sendsz, recvsz);
break;
default:
goto err;
}
|
これらのルーチンを使用するときは、ファイル記述子がオープンされて結合されている必要があります。svcaddr はサーバーのアドレスです。
次に、ボトムレベルのサーバーを作成する例を示します。
/*
* 使用する変数
* xprt: SVCXPRT *
*/
switch(tinfo.servtype) {
case T_COTS_ORD:
case T_COTS:
xprt = svc_vc_create(fd, sendsz, recvsz);
break;
case T_CLTS:
xprt = svc_dg_create(fd, sendsz, recvsz);
break;
default:
goto err;
}
|