The goal of remote procedure call is to make the invocation of a procedure on a remote machine appear as though it were local.
The local procedure calls a stub which marshalls the paramaters and packs the call into a message to the remote machine.
On the remote machine there is another stub which unpacks the parameters and calls a local procedure to do the work. This passes the reults back to the stub which packs the result back up and sends it back over the network to the originating stub, which upnacks the result and returns it to the original calling procedure.
Sun provides tools that build the stubs automatically. The following example shows their use.
This file contains the information that the two ends need to know in order to match the called process.
/* date.x */
/*
* Define 2 procedures:
* bin_date_l() returns the binary time and date (no arguments)
* str_datel() takes a binary time and returns a human readable string
*/
program DATE_PROG {
version DATE VERS {
long BIN_DATE(void) = 1; /* procedure number */
string STR_DATE(long) = 2; /* procedure number */
} = 1; /* version number */
} = 0x31234567; /* program number */
If you compile this with rpcgen you get date.h Which looks like this.
#define DATE_PROG ((u_log)0x31234567) #define DATE_VERS ((u_long)1) #define BIN_DATE ((u_long)1) extern long *bin_date_1(); #define STR_DATE ((u long)2) extern char **str_date_1();
You should NEVER edit this file directly. rpcgen also makes two other files
The programmer needs to write the server procedures.
In this case these are in a file date_proc.c
/* * dateproc.c - remote proceduies; called by server stub. */ #include/* standard RPC include file */ #include "date.h" /* this file is generated by rpcgen */ /* * Return the binary date and time. */ long * bin_date_1() { static long timeval; /* must be static */ long time(); /* Unix function */ timeval = time((long *) 0); return(&timeval); } /* * Convert a binary time and return a human readable */ char ** str_date_1(bintime) long *bintime; { static char *ptr; /* must be sttic */ char *ctime(); /* Unix function */ ptr = ctime(bintime); /* convert to local time */ return(&ptr); /* return the address of pointer */ }
The client procedure is contained in rdate.c
/* * rdate.c - client program for remote date service */ #include#include /* standard RPC include file */ #include "date.h" /* this file is generated by rpcgen */ main(argc, argv) int argc; char *argv []; { CLIENT *cl; /* RPC handle */ char *server; long *lresult; /* return Value from bin_date() */ char **sresult; /* return value form str_date() */ if (argc != 2){ fprintf(stderr, "usage: ~s hostname\n", argv[0]); exit(1); } server= argv[1]; /* * Create the client "handle." */ if ( (cl = clnt_create(server, DATE_PROG, DATE_VERS, "udp")) == NULL) { /* * Couldn't establish Connection with server. */ clnt_pcreateerror(server): exit(2); } /* * First call the remote procedure "bin_date" */ if ( (lresult = bin_date_1(NULL, cl)) == NULL) { clnt_perror(cl, server) ; exit(3); } printf("time on host %s = %ld\n", server, *lresult); /* Now call the remote procedure "str date"*/ if ( (sresult = str_date_1(lresult, cl)) == NULL) { clnt_perror(cl, server); exit(4); } printf("time on host %s = %s", server, *sresult); clnt_destroy(cl); /* done with the handle */ exit(0); }
To generate the server type
gcc -o date_svc date_proc.c date_svc.c -lnsl
To generate the client
gcc -o rdate rdate.c date_clnt.c -lnsl
You then run the server in the background on one machine, (eg hollerith). You run the client by typing: rdate hollerith at another machine.
Return to Networks home
page
Return
to Systems Programming Home Page