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