RPC のブロードキャストが要求されると、メッセージはネットワーク上の rpcbind デーモンに送られます。要求されたサービスが登録されている rpcbind デーモンは、その要求をサーバーに送ります。ブロードキャスト RPC と通常の RPC 呼び出しとの主な相違点を次に示します。
通常の RPC では応答は 1 つです。ただし、ブロードキャスト RPC には複数の応答があります (メッセージに応答するすべてのマシンから応答が返されます)。
ブロードキャスト RPC は、UDP のようにブロードキャスト RPC をサポートする非接続型プロトコルでしか使用できません。
ブロードキャスト RPC では、正常終了以外の応答は返されません。したがって、ブロードキャスタとリモートのサービスでバージョンの不一致があれば、サービスからブロードキャスタには何も返されません。
ブロードキャスト RPC では、rpcbind で登録されたデータグラムサービスだけがアクセス可能です。サービスアドレスはホストごとに異なるので、rpc_broadcast() は、rpcbind のネットワークアドレスにメッセージを送信します。
ブロードキャスト要求のサイズはローカルネットワークの最大伝送ユニット (MTU:maximum trasfer unit) により制限されます。Ethernet の MTU は 1500 バイトです。
次に、rpc_broadcast() の使用方法を示し、引数を説明します。
/*
* bcast.c: RPC ブロードキャストの使用例
*/
#include <stdio.h>
#include <rpc/rpc.h>
main(argc, argv)
int argc;
char *argv[];
{
enum clnt_stat rpc_stat;
rpcprog_t prognum;
rpcvers_t vers;
struct rpcent *re;
if(argc != 3) {
fprintf(stderr, "usage : %s RPC_PROG VERSION\n", argv[0]);
exit(1);
}
if (isdigit( *argv[1]))
prognum = atoi(argv[1]);
else {
re = getrpcbyname(argv[1]);
if (! re) {
fprintf(stderr, "Unknown RPC service %s\n", argv[1]);
exit(1);
}
prognum = re->r_number;
}
vers = atoi(argv[2]);
rpc_stat = rpc_broadcast(prognum, vers, NULLPROC, xdr_void,
(char *)NULL, xdr_void, (char *)NULL, bcast_proc,
NULL);
if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) {
fprintf(stderr, "broadcast failed: %s\n",
clnt_sperrno(rpc_stat));
exit(1);
}
exit(0);
}
|
例 5–3 の関数では、ブロードキャストに対する応答を収集します。通常は、最初の応答だけを取り出すか、応答をすべて収集します。bcast_proc() は、応答を返したサーバーの IP アドレスを表示します。この関数は FALSE を返して応答の収集を続けます。したがって、RPC クライアントコードはタイムアウトになるまでブロードキャストを再送信し続けます。
bool_t
bcast_proc(res, t_addr, nconf)
void *res; /* 応答なし */
struct t_bind *t_addr; /* 応答したアドレス */
struct netconfig *nconf;
{
register struct hostent *hp;
char *naddr;
naddr = taddr2naddr(nconf, &taddr->addr);
if (naddr == (char *) NULL) {
fprintf(stderr,"Responded: unknown\n");
} else {
fprintf(stderr,"Responded: %s\n", naddr);
free(naddr);
}
return(FALSE);
}
|
TRUE が返されるとブロードキャストは終了し、rpc_broadcast() は正常終了します。FALSE が返された場合は、次の応答を待ちます。数秒間待ってから、要求が再びブロードキャストされます。応答が返されない場合は、rpc_broadcast() は RPC_TIMEDOUT を返します。