next up previous
Next: Transparent RPC Up: Communication across a Network Previous: OS Interface: Sockets


Sockets require a client to encode its request and parameters in the data area of the message, and then wait for a reply. The server in turn needs to decode the request, perform the service, and then encode the reply. In other words, the client and server must use remote assignment semantics to request and respond to service requests. It would be more useful if the client could directly call a remote procedure which the server executes to service the request.

Sun RPC demonstrates how a remote procedure call paradigm can be supported on top of sockets via library routines rather than compiler support. Each server registers a procedure pair via the registerrpc call:

registerrpc (prognum, versnum, procnum, procaddr, inproc, outproc)
A client can invoke callrpc to call the remote procedure:
callrpc (host, prognum, versum, procnum, inproc, &in, outproc, &out)
The procedure callrpc takes as arguments the machine number of the server, the procedure identifier, and the input and output parameters. It sends an appropriate UDP or TCP message to the destination machine, waits for a reply, extracts the results, and returns them in the output parameters.

The XDR (eXternal Data Routines) are responsible for marshalling/unmarshalling procedure parameters onto/from XDR streams.

To illustrate, an add server, that adds an integer and a float, can declare the following ``interface'' in a header file:

#define PROGNUM 1
#define VERSNUM 0
#define ADDNUM  0

typedef struct {
    int f1;
    float f2 } S;

extern float add ();

Then it can provide an implementation of the add procedure:

float add (s)
	S *s;
    return (s->f1 + s->f2);

A procedure such as add that can be called remotely by Sun RPC is required to take a one-word argument. It takes only one argument so that callrpc does not have to deal with a variable number of arguments. Like any other procedure, callrpc has to fix the type of the argument. The trick to passing a user-defined value to a remote procedure through callrpc is to pass its address and then let the procedure cast it as a pointer to a value of the correct type.

Next it can provide an implementation of the following xdr procedure between the client and server:

xdr_s (xdrsp, arg)
    XDRS *xdrsp;
    S *arg;
    xdr_int (xdrsp, &arg->f1);
    xdr_float (xdrsp, &arg->f2);

It is called in the marshalling/unmarshalling modes by the client and server RPC system. In the marshalling mode, it writes the argument onto the stream and in the unmarshalling mode it extracts data from the stream into the argument.

Finally, it can register the procedure with the RPC system:

registerrpc (PROGNUM, VERSNUM, ADDNUM, add, xdr_s, xdr_float )
Once it has registered all of its procedures, it can execute
to wait for invocations of its registered procedures. A client can now execute the procedure:
S *s;
float *result;

s->f1 = 3;
s-f2 = 4.12;

callrpc (host, PROGNUM, VERSNUM, ADDNUM, xdr_s, s, xdr_float, result);

svc_run() is a looping select operation, which:

1. blocks the receiver until one of its registered procedures is invoked,

2. services the call

3. goes back to 1.

Sun RPC is built on top of the socket layer, and svc_run() calls the Unix select() call. An RPC program may wish to have control over the loop execute by svc_run(). For example, it may wish to read data from files, or communicate via sockets, or poll (rather than block) for RPC calls. Sun RPC allows programs to invoke the select() call manually. A special call, svc_fds() returns the bit mask describing the socket(s) created by RPC, which can be passed to the select() call. The operation, svc_getreq() can be used to service an RPC message when activity occurs on these sockets. For polling, the operations, poll(), svc_pollfd(), and get_req_poll() are provided.

next up previous
Next: Transparent RPC Up: Communication across a Network Previous: OS Interface: Sockets
Prasun Dewan 2006-02-02