The following is an example of the lowest layer of RPC on the client side program:
#define RMTPROGNUM (u_long)0x3fffffffL #define RMTPROGVER (u_long)0x1L #define STRINGPROC (u_long)2 #include <stdio.h> #include <rpc\rpc.h> #include <sys\socket.h> #include <netdb.h> main(argc, argv) int argc; char *argv[ ]; { struct hostent *hp; struct timeval pertry_timeout, total_timeout; struct sockaddr_in server_addr; int sock = RPC_ANYSOCK; static char buf[100], *strc_in= "Hello", *strc_out=buf; char *parrc_in, *parrc_out; register CLIENT *clnt; enum clnt_stat cs; ... /* get the Internet address of RPC server host */ if ((hp = gethostbyname("RPCSERVER_HOST")) == NULL) { fprintf(stderr,"Can't get address for %s\n","RPCSERVER_HOST"); exit (-1); } pertry_timeout.tv_sec = 3; pertry_timeout.tv_usec = 0; /* set sockaddr_in structure */ bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr.s_addr, hp->h_length); server_addr.sin_family = AF_INET; server_addr.sin_port = 0; /* create clnt TCP handle */ if ((clnt = clnttcp_create(&server_addr, RMTPROGNUM, RMTPROGVER, &sock, 1024*10, 1024*10)) == NULL) { clnt_pcreateerror("clnttcp_create fail"); /* Why failed ? */ exit(-1); } /* * create clnt UDP handle * if ((clnt = clntudp_create(&server_addr, RMTPROGNUM, RMTPROGVER, * pertry_timeout, &sock)) == NULL) * { * clnt_pcreateerror("clntudp_create fail"); * exit(-1); * } */ total_timeout.tv_sec = 10; total_timeout.tv_usec = 0; ... /*call the remote procedure STRINGPROC associated with */ /*client handle (clnt) */ cs=clnt_call(clnt, STRINGPROC,xdr_wrapstring, (char *)&strc_in[j], xdr_wrapstring, (char *)&strc_out,total_timeout); if (cs != RPC_SUCCESS) printf("*Error* clnt_call fail :\n"); clnt_destroy(clnt); /* deallocate any memory associated */ /* with clnt handle */ ... }
The following steps describe the lowest layer of RPC on the client side program:
Use the gethostbyname() call to determine the internet address of the host, which is running the RPC server. Initialize the socaddr_in structure, found in the <NETINET\IN.H> header file.
If you are not familiar with socket calls, see Sockets General Programming Information.
The clnttcp_create() and clntudp_create() calls create TCP and UDP client RPC handles (CLIENT), respectively. The CLIENT structure is defined in the <RPC\CLNT.H> header file.
There are six parameters for the clnttcp_create() call:
The low-level version of the callrpc() call is the clnt_call(), which has seven parameters:
The return code RPC_SUCCESS indicates a successful call; otherwise, an error has occurred. You find the RPC error code in the <RPC\CLNT.H> header file.
The clnt_destroy() call always deallocates the space associated with the client handle. If the RPC library opened the socket associated with the client handle, the clnt_destroy() call closes it. If you open the socket, it stays open.