Introduction to programming with Sun/ONC RPC

Tutorial

This page illustrates the basics of using ONC (Sun) remote procedure calls (RPC). We'll start with a remote procedure to add two numbers. This program will accept two numbers from the command line, parse the ascii text to convert them to numbers, then call a remote procedure to add them and print the results.

Step 1. Create the IDL

The first step involves defining the interface. This has to abide by Sun's format for its Interface Definition Language (IDL). An IDL is a file (suffixed with .x) which optionally begins with a bunch of type definitions and then defines the remote procedures. A set of remote procedures are grouped into a version. One or more versions are grouped into a program.

Traditionally, ONC RPC restricted us to remote procedures that accept a single parameter and return a single parameter. Later versions added an option to support multiple parameters, but we'll stick with the traditional mechanism to provide greatest compatibility. The lack of multiple parameters isn't really a problem since all we need to do is define a data structure that holds all the parameters we need.

In this example we have one type definition to define a structure that holds two integers: this will be our input parameter for the add function. Our interface will also have one version and one progam. We have to assign a number to each function, version, and program. The function will be given an ID of 1. So will the version. The program number is a 32-bit number. Sun reserved the range from 0 to 0x1fffffff. We'll number this program 0x23451111.

The IDL, which we'll put in a file named add.x looks like:

struct intpair { int a; int b; }; program ADD_PROG { version ADD_VERS { int ADD(intpair) = 1; } = 1; } = 0x23451111;

We can compile this to test if we missed anything:

rpcgen -C add.x
The -C flag (upper-case C) tells rpcgen to generate C code that conforms to ANSI C. This is the default on some versions of rpcgen. If we look at the files that were generated, we'll see:
add.h
This is the header file that we'll include in both our client and server code. It defines the structure we defined (intpair) and typedefs it to a type of the same name. It also defines the symbols ADD_PROG (0x23451111, our program number) and ADD_VERS (1, our version number). Then it defines the client stub interface (add_1) and the interface for the server-side function that we'll have to write (add_1_svc). In the past (pre ANSI-C), the client stub and server side functions had the same name but since ANSI C was strict with parameters matching their declarations, this was changed since the parameters are slightly different. As we'll soon see, the client stub accepts an extra parameter representing a handle to the remote server. The server function gets an extra parameter containing information about who is making the connection.
add_svc.c
This is the server program. If you look at the code, you'll see that it implements the main procedure which registers the service and, if the symbol RPC_SVC_FG is not defined, forks a process to cause the service to run in the background; the parent exits.

The program also implements the listener for the program. This is the function named add_prog_1 (the _1 is used to distinguish the version number. The function contains a switch statment for all the remote procedures supported by this program and this version. In addition to the null procedure (which is always supported), the only entry in the switch statement is ADD, for our add function. This sets a function pointer (local) to server function, add_1_svc. Later in the procedure, the function is invoked with the unmarshaled parameter and the requestor's information.

add_clnt.c
This is client stub function that implements the add_1 function. It marshals the parameter, calls the remote procedure, and returns the result.
add_xdr.c
The _xdr.c file is not always generated; it depends on the parameters used for remote procedures. This file contains code to marshal parameters for teh intpair structure. It uses XDR (eXternal Data Representation) libraries to convert the two integers into a standard form.

Continue to step 2