デバッグツールとして、ネットワーク機能をすべてバイパスする 2 つの擬似 RPC インタフェースがあります。ルーチン clnt_raw_create() と svc_raw_create() は、実際のトランスポートを使用しません。
製品システムで RAW モードは使用しないでください。RAW モードは、デバッグを行い易くするために使用します。RAW モードはマルチスレッド対応ではありません。
例 4-19 は、次の Makefile を使用してコンパイルとリンクが行われます。
all: raw CFLAGS += -g raw: raw.o cc -g -o raw raw.o -lnsl
/* * 数値を 1 増加させる簡単なプログラム */ #include <stdio.h> #include <rpc/rpc.h> #include <rpc/raw.h> #define prognum 0x40000001 #define versnum 1 #define INCR 1 struct timeval TIMEOUT = {0, 0}; static void server(); main (argc, argv) int argc; char **argv; { CLIENT *cl; SVCXPRT *svc; int num = 0, ans; int flag; if (argc == 2) num = atoi(argv[1]); svc = svc_raw_create(); if (svc == (SVCXPRT *) NULL) { fprintf(stderr, "Could not create server handle¥n"); exit(1); } flag = svc_reg( svc, prognum, versnum, server, (struct netconfig *) NULL ); if (flag == 0) { fprintf(stderr, "Error: svc_reg failed.¥n"); exit(1); } cl = clnt_raw_create( prognum, versnum ); if (cl == (CLIENT *) NULL) { clnt_pcreateerror("Error: clnt_raw_create"); exit(1); } if (clnt_call(cl, INCR, xdr_int, (caddr_t) &num, xdr_int, (caddr_t) &ans, TIMEOUT) != RPC_SUCCESS) { clnt_perror(cl, "Error: client_call with raw"); exit(1); } printf("Client: number returned %d¥n", ans); exit(0); } static void server(rqstp, transp) struct svc_req *rqstp; SVCXPRT *transp; { int num; fprintf(stderr, "Entering server procedure.¥n"); switch(rqstp->rq_proc) { case NULLPROC: if (svc_sendreply( transp, xdr_void, (caddr_t) NULL) == FALSE) { fprintf(stderr, "error in null proc¥n"); exit(1); } return; case INCR: break; default: svcerr_noproc(transp); return; } if (!svc_getargs( transp, xdr_int, &num)) { svcerr_decode(transp); return; } fprintf(stderr, "Server procedure: about to increment.¥n"); num++; if (svc_sendreply(transp, xdr_int, &num) == FALSE) { fprintf(stderr, "error in sending answer¥n"); exit (1); } fprintf(stderr, "Leaving server procedure.¥n"); } |
次の点に注意してください。
サーバーはクライアントより先に作成しなければなりません。
svc_raw_create() には引数がありません。
サーバーは rpcbind デーモンに登録されません。svc_reg() の最後の引数は (struct
netconfig *) NULL ですので、rpcbind デーモンに登録されないことがわかります。
svc_run() が呼び出されません。
RPC 呼び出しはすべて同一の制御スレッド内で行われます。