Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
4.  Programmer's Interface to RPC Standard Interfaces Low-Level Data Structures   Previous   Contents   Next 
   
 

Testing Programs Using Low-Level Raw RPC

Two pseudo-RPC interface routines bypass all the network software. The routines shown in clnt_raw_create() and svc_raw_create() do not use any real transport.


Note - Do not use raw mode on production systems. Raw mode is intended as a debugging aid only. Raw mode is not MT safe.


The following code example is compiled and linked using the following makefile:

all: raw
CFLAGS += -g
raw: raw.o
cc -g -o raw raw.o -lnsl 

Example 4-19 Simple Program Using Raw RPC

/*
 * A simple program to increment a number by 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");
} 

Note the following points about the example:

  • The server must be created before the client.

  • svc_raw_create() has no parameters.

  • The server is not registered with rpcbind. The last parameter to svc_reg() is (struct netconfig *) NULL.

  • svc_run() is not called.

  • All the RPC calls occur within the same thread of control.

  • The server-dispatch routine is the same as for normal RPC servers.

 
 
 
  Previous   Contents   Next