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. |
VOID keyword.
| Top | Master Index | Keywords | Functions |