RPC Programming quick start
Netbula
RPCGen
Netbula
Portmapper service
RPC
Programming Quick Start
If you are not familiar
with ONC RPC, then the book "Power Porgramming RPC" from O'Reilly
is a useful guide. Also, there is extensive online
documentation for programming ONC RPC from DEC.
The following is a sample program included under the samples/MyMgSvc/
folder of the ONC RPC SDK.
1) Define the RPC Interface in a .x file.
struct aTypeStruct {
int i;
double d;
};
typedef struct aTypeStruct aType;
program MyRPCService {
version ThisVersion {
aType function_foo(int) = 1;
int function_bar(aType) =2;
}=1;
}=34567;
Here, we defined an RPC interface with program number 34567, and two procedures
function_foo and function_bar, save it to a file named MyRPCService.x
.
2) Use RPCGen to compile the .x file
% rpcgen MyRPCService.x
type the command
"rpcgen MyRPCService.x" at the command prompt. This will produce the
following files
- MyRPCService.h
--- the common header file for the RPC, read the generated comments.
- MyRPCService_xdr.c
--- the XDR routine for struct aType. This file will be used by both
the client and the server.
- MyRPCService_cln.c
--- The generated client stub. An RPC client application calls the
functions defined in this file.
- MyRPCService_svc.c
--- The generated server stub.
- MyRPCService_imp.tmp.c
--- The server implmentation template, you copy this file and fill
in the server implementation.
- MyRPCService.hpp
---- The C++ class for the client
- MyRPCService.mak
---- Makefile, you need to edit this
3) Code the server
implementation
The MyRPCService.h
file included the declarations for two functions function_foo_svc()
and function_bar_svc(), the RPC server programmer must implement
these two functions to do the real work. Let's assume the implemtation
is coded in the file MyRPCService_imp.c .
Rpcgen generates a server implementation template file, you can copy
it over and fill in the details.
4) Build and run
the server
Compile the MyRPCService_xdr.c,
MyRPCService_svc.c and MyRPCService_imp.c files. Make sure the include/
directory of the Netbula ONC RPC SDK is in the include path. Link
with the pwrpc32.lib import library to build an executable. When
you run the built RPC server/client, make sure pwrpc32.dll can
be found by the application.
The ONC RPC SDK
contains a makefile template which can be easily modified to use for
this sample application.
To run the RPC server,
first start the portmapper (pmapsvc or portmap.exe), then start MyRPCService
server we just build.
5) Write a client
The client code
looks like this:
int i;
aType a, *ap;
CLIENT * cl =
clnt_create("server_host_name", program_number, version_number, "tcp");
ap = function_foo_1(&i, cl);
i = function_bar_1(&a, cl);
RPCGEN also generates C++ code for the client. The client calling code is listed in cxx_client_main.cpp.
#include <stdio.h>
#include <rpc/rpc.h>
/* we must define RPC_CLIENT in the client */
#define RPC_CLIENT
#include "MyRPCService.hpp"
int main(int argc, char*argv[])
{
int i=100, i2=0;
aType atype;
int result_code=0;
CMyRPCService client("localhost", "udp");
CLIENT* cl = client.getHandle();
//check for create error
if (cl == NULL) {
client.pcreateerror(argv[1]);
exit (1);
}
result_code = client.function_foo_1(&i, &atype);
if(result_code ==0) {
printf("Got reply {%d, %f}\n", atype.i, atype.d);
}else {
client.perror("MyRPC");
}
if(0==(result_code = client.function_bar_1(&atype, &i2))) {
printf ("Got reply %d\n", i2);
}else {
client.perror("MyRPC");
}
xdr_free((xdrproc_t)xdr_aType, (char*) &atype);
client.destroy();
return 0;
}
|
Netbula RPCGen Usage
The following is modified from rpcgen(1) man page on UNIX systems.
NAME
rpcgen
- an RPC protocol compiler
USAGE
- rpcgen
infile
- rpcgen
-c|-h|-l|-m [-o outfile] infile
- rpcgen
-s transport [-o outfile] infile
DESCRIPTION
rpcgen
is a compiler that generates C source code from a protocol specification
file (normally with .x suffix). When run without additional options
flags, rpcgen produces the following C files from a input file
named proto.x
- proto.h
Header file for data types and function prototypes.
- proto_xdr.c
XDR routines to encode/decode arguments and return values, used
by both the client and the server.
- proto_svc.c
Server side stub. This contains mainly the code to start and register
the server and the dispatch routine that receives client call requests
and dispatch the calls to the server implementation functions.
- proto_clnt.c
Client side stub.
The C-preprocessor,
CPP, is used by rpcgen to preprocess the input file. Therefore,
rpcgen does not interprets the .x file directly, instead it
operates on the output from CPP. rpcgen does multiple
passes to generate each type of the files listed above, during each
pass, it defines a different CPP symbol:
- RPC_HDR defined
when compiling into header files
- RPC_XDR defined
when compiling into XDR routines
- RPC_SVC defined
when compiling into server-side stubs
- RPC_CLNT
defined when compiling into client-side stubs
For instance,
to produce the header file proto.h from proto.x, rpcgen
goes through the following steps
- CPP
-DRPC_HDR USER_CPP_FLAGS proto.x > tmpfile
- compile tmpfile
into proto.h
- remove tmpfile
Netbula
RPCGen for Win32
uses CL.EXE in MS Visual C++ as the default C-preprocessor
(with flags /C /EP /nologo). The CL.EXE must be in the search
path, or rpcgen will spit out a "preprocessing failed"
error. VC++ come with script named vcvars32.bat which does the proper
environment setting.
You can let rpcgen use a different CPP by setting two environment
variables, RPCGEN_CPP and RPCGEN_CPP_FLAG, for the
CPP program and associated flags, respectively. |
Rpcgen does a
little preprocessing of its own. Any line beginning with `%' is passed
directly into the output file, uninterpreted by rpcgen.
You can customize some of your XDR routines by leaving those data
types undefined. For every data type that is undefined, rpcgen will
assume that there exists a routine with the name xdr_ prepended to
the name of the undefined type.
OPTIONS
Flag
|
Argument
|
Description
|
-c |
none |
Compile
into XDR routines. |
-h |
none |
Compile
into C data-definitions (a header file) |
-l |
none |
Compile
into client-side stubs. |
-m |
none |
Compile
into server-side stubs, but do not generate the "main"
function. This option is useful for doing callback-routines and
for people who need to write their own "main" function
to do initialization. |
-o
|
output
filename |
Specify the name of the output file. If none is specified, standard
output is used (-c, -h, -l and -s modes only). |
-s |
transport
name
(udp or tcp) |
Compile
into server-side stubs, using the the given transport. The supported
transports are udp and tcp. This option may be invoked
more than once so as to compile a server that serves multiple
transports. When this option is not given, rpcgen generates a
server that listens on both the UDP and the TCP transport. |
Portmapper
service (Windows NT/2K/XP only)
When an RPC server
starts up, it registers its program number and port with the Portmapper
on its local machine. Before a client calls an RPC, it must contact
the portmapper running on the server machine to find out the port
number of the RPC server.
To install the
portmap service, run from command line
> pmapsvc
-i
To uninstall,
run from command line
> pmapsvc
-u
To see the status,
> pmapsvc
-v
To get help, run pmapsvc -h
To start the
service, go to control panel, open the icon services, find the PowerRPC
Portmapper and start it.
Contact support@netbula.com for more questions.