Specifications
Remote Procedure Call Programming Guide Page 11
First, the server gets a transport handle, which is used for receiving and replying to RPC messages. regis-
terrpc() uses svcudp_create() to get a UDP handle. If you require a more reliable protocol, call svctcp_cre-
ate() instead. If the argument to svcudp_create() is RPC_ANYSOCK the RPC library creates a socket on
which to receive and reply to RPC calls. Otherwise, svcudp_create() expects its argument to be a valid
socket number. If you specify your own socket, it can be bound or unbound. If it is bound to a port by the
user, the port numbers of svcudp_create() and clnttcp_create() (the low-level client routine) must match.
If the user specifies the RPC_ANYSOCK argument, the RPC library routines will open sockets. Otherwise
they will expect the user to do so. The routines svcudp_create() and clntudp_create() will cause the RPC
library routines to bind() their socket if it is not bound already.
A service may choose to register its port number with the local portmapper service. This is done is done by
specifying a non-zero protocol number in svc_register(). Incidently, a client can discover the server’s port
number by consulting the portmapper on their server’s machine. This can be done automatically by speci-
fying a zero port number in clntudp_create() or clnttcp_create().
After creating an SVCXPRT, the next step is to call pmap_unset() so that if the nusers() server crashed ear-
lier, any previous trace of it is erased before restarting. More precisely, pmap_unset() erases the entry for
RUSERSPROG from the port mapper’s tables.
Finally, we associate the program number for nusers() with the procedure nuser(). The final argument to
svc_register() is normally the protocol being used, which, in this case, is IPPROT O_UDP Notice that unlike
registerrpc(), there are no XDR routines involved in the registration process. Also, registration is done on
the program, rather than procedure, level.
The user routine nuser() must call and dispatch the appropriate XDR routines based on the procedure num-
ber. Note that two things are handled by nuser() that registerrpc() handles automatically. The first is that
procedure NULLPROC (currently zero) returns with no results. This can be used as a simple test for detect-
ing if a remote program is running. Second, there is a check for invalid procedure numbers. If one is
detected, svcerr_noproc() is called to handle the error.
The user service routine serializes the results and returns them to the RPC caller via svc_sendreply() Its first
parameter is the SVCXPRT handle, the second is the XDR routine, and the third is a pointer to the data to be
returned. Not illustrated above is how a server handles an RPC program that receives data. As an example,
we can add a procedure RUSERSPROC_BOOL which has an argument nusers(), and returns TRUE or
FALSE depending on whether there are nusers logged on. It would look like this:
case RUSERSPROC_BOOL: {
int bool;
unsigned nuserquery;
if (!svc_getargs(transp, xdr_u_int, &nuserquery) {
svcerr_decode(transp);
return;
}
/*
* Code to set nusers = number of users
*/
if (nuserquery == nusers)
bool = TRUE;
else
bool = FALSE;
if (!svc_sendreply(transp, xdr_bool, &bool)) {
fprintf(stderr, "can’t reply to RPC call\n");
return (1);
}
return;
}