ONC+ 開発ガイド

サーバー側

例 4–13 に、対応するサーバー側プログラム svcudp_create() を示します。サーバー側では svc_tli_create() を使用します。

svc_tli_create() は、アプリケーションで次のように詳細な制御を行う必要があるときに使用します。

サービスを rpcbind により登録するには、rpcb_set() を使用します。


例 4–13 下位レベル RPC を使用したサーバー側プログラム

#include <stdio.h>
#include <rpc/rpc.h>
#include <netconfig.h>
#include <netinet/in.h>
 
SVCXPRT *
svcudp_create(fd)
	register int fd;
{
 struct netconfig *nconf;
	SVCXPRT *svc;
	int madefd = FALSE;
	int port;
	void *handlep;
 struct  t_info tinfo;
 
	/* どのトランスポートも使用不可の場合 */
 if ((handlep = setnetconfig() ) == (void *) NULL) {
		nc_perror("server");
 	return((SVCXPRT *) NULL);
	}
	/*
  * 非接続型で、プロトコルファミリが INET、名前が UDP の
	 * トランスポートが見つかるまで探す。
  */
	while (nconf = getnetconfig( handlep)) {
 	if ((nconf->nc_semantics == NC_TPI_CLTS) &&
		    (strcmp( nconf->nc_protofmly, NC_INET) == 0 )&&
		    (strcmp( nconf->nc_proto, NC_UDP) == 0 ))
			break;
 }
	if (nconf == (struct netconfig *) NULL) {
 	endnetconfig(handlep);
		return((SVCXPRT *) NULL);
 }
	if (fd == RPC_ANYFD) {
		fd = t_open(nconf->nc_device, O_RDWR, &tinfo);
		if (fd == -1) {
			(void) endnetconfig();
			return((SVCXPRT *) NULL);
 	}
		madefd = TRUE;
	} else
 	t_getinfo(fd, &tinfo);
	svc = svc_tli_create(fd, nconf, (struct t_bind *) NULL,
	                      tinfo.tsdu, tinfo.tsdu);
	(void) endnetconfig(handlep);
 if (svc == (SVCXPRT *) NULL) {
		if (madefd)
 		(void) t_close(fd);
		return((SVCXPRT *)NULL);
 }
	return (svc);
}

この例では、clntudp_create() と同じ方法でネットワーク選択を行なっています。svc_tli_create() で結合しているため、ファイル記述子は明示的にはトランスポートアドレスと結合されません。

svcudp_create() はオープンしている fd を使用できます。有効なファイル記述子が渡されなければ、選択された netconfig 構造体を使用してこのルーチン内でオープンします。