RPC has a concept of clients and servers.
The easiest way to start with RPC is to use a program called rpcgen this reads a file that describes the required interface between client and server and generates C code that you can include in your client and server.
prog.x --> rpcgen ---> prog.h Header file ---> prog_clnt.c Client stubs file ---> prog_svc.c Server stubs file ---> prog_xdr.c XDR routines (more later).You write prog.x and rpcgen generates prog.h prog_clnt.c prog_svc.c prog_xdr.c You then write the client and server and link them with the rpcgen code to complete the RPC system.
client.c -----> client executable prog.h ---| prog_clnt.c ---| prog_xdr.c ---| server.c -----> Server executable prog.h ---| prog_svc.c ---| prog_xdr.c ---|Ok, time for some examples.
void.x |
---|
/* RPCGEN code decribing the client/server API. */ program MJLPROG { version MJLVERS { void VOID(void) = 1; } = 1; } = 0x20000001; |
void.x describes the RPC interface between the client and server. There are some important items to note here.
program MJLPROG { } = 0x20000001; |
This is the RPC program number. It is used by the client to identify the server it intends to use. It is important that you provide a unique number here. You can see which values are in use with the Unix command rpcinfo -p or by looking at /etc/rpc. Please note that the number is supplied in void.x as a hex value but shown as a decimal value by rpcinfo One other point, you should only use values in the range 0x20000000 0x3FFFFFFF as these have been reserved for use local use. |
version MJLVERS { } = 1; |
The RPC Version number. |
void VOID(void) = 1; |
This defines the only RPC function that the server will provide. |
void_client.c |
---|
#include <rpc/rpc.h> #include "void.h" main() { CLIENT *pclnt; void *pVoid; char Host[256]; /* Get the name of the host running the server. */ gethostname(Host, 256); /* Connect to the server. */ pclnt = clnt_create(Host, MJLPROG, MJLVERS, "udp"); /* Issue a request to the server. */ void_1(pVoid, pclnt); /* Disconnect from the server. */ clnt_destroy(pclnt); } |
#include <rpc/rpc.h> |
Include the standard RPC headers. |
#include "void.h" |
Include the header file generated by rpcgen |
pclnt = clnt_create(); |
Connect to the server MJLPROG on Host and return a pointer to the CLIENT control structure. |
void_1(pVoid, pclnt); |
Call the remote function. |
clnt_destroy(); |
Disconnect from the server. |
void_server.c |
---|
#include |
void *void_1_svc() |
The server function that will be run for the client. |
Please note that the server does not have a main(), rpcgen generates it for you.
The code can be compiled with the following commands
gcc void_server.c void_svc.c -o void_server gcc void_client.c void_clnt.c -o void_client
In theory you should be able to start the server and it will respond everytime the client is executed. I have not included any error recovery into this example as it makes the code harder to read. As an exercise try adding the error recovery code yourself :-)
integer.x |
---|
/* RPCGEN code decribing the client/server API. */ program MJLPROG { version MJLVERS { int INTEGER(int) = 1; } = 1; } = 0x20000001; |
int INTEGER(int) = 1; |
Server function now accepts an integer and returns an integer. |
Top | Master Index | Keywords | Functions |