This chapter is for RPC programmers. It explains:
· What components a distributed application contains
· How to use ONC RPC to develop a distributed application, step by step
· How to use the RPCINFO utility
The below table lists the components of a distributed application.
Component |
Description |
Main program (client) |
An ordinary main program that calls a remote procedure as if local |
Network interface |
Client and server stubs, header files, XDR routines for input arguments and results |
Server procedure |
Carries out the client's request (at least one is required) |
These components may be written in any high-level language. The ONC RPC Run-Time Library (RTL) routines are written in C language.
The following steps summarize what you need to do to build a distributed application:
1. Design the application.
2. Write an RPC interface definition. Compile it using RPCGEN, then edit the output files as necessary. (This step is optional. An RPC interface definition is not required. If you do not write one, proceed to step 3.)
3. Write any necessary code that RPCGEN did not generate.
4. Compile the RPCGEN output files, server procedures, and main program using the appropriate language compiler(s).
5. Link the object code, making sure you link in the ONC RPC RTL.
6. Start the Port Mapper on the server host.
7. Execute the client and server programs.
You must write a main (client) program and at least one server procedure. The network interface, however, may be hand-written or created by RPCGEN. The network interface files contain client and server stubs, header files, and XDR routines. You may edit any files that RPCGEN creates.
When deciding whether to write the network interface yourself, consider these factors:
Is execution time critical? |
Your hand-written code may execute faster than code that RPCGEN creates. |
Which RPC interface layer do you want to use? |
RPCGEN permits you to use only the highest layer interface. If you want to use the lower layers, you must write original code. The ONC RPC Fundamentals, Chapter 12, describes the characteristics of each RPC interface layer. |
Which transport protocol do you want to use? |
|
ONC: If you use an asynchronous transport (UDPA or TCPA), you must either write original code for the server stubs or edit the RPCGEN output.
You may write your own XDR programs, but it is usually best to let RPCGEN handle these.
An interface definition is a program the RPCGEN compiler accepts as input. The RPCGEN Compiler, Chapter 14, explains exactly what interface definitions must contain.
Interface definitions are optional. If you write the all of the network interface code yourself, you do not need an interface definition.
You must write an interface definition if you want RPCGEN to generate network interface code.
After compiling the interface definition, edit the output file(s).
If you are not writing an interface definition, skip this step and proceed to step 3.
Write any necessary code that RPCGEN did not create for you. The below table lists the texts you may use as references.
Reference |
Purpose |
RFC 1057 |
Defines the RPC language. Use for writing interface definitions. |
RFC 1014 |
Defines the XDR language. Use for writing XDR filter routines. |
The ONC RPC RTL Client Routines chapter and those that follow |
Defines each routine in the ONC RPC RTL. Use for writing stub procedures and XDR filter routines. |
If an input argument or result is not an integer, you need to create a structure for it in the RPCGEN input file. RPCGEN converts the structure to C format and creates XDR code to encode and decode it.
The TCPWARE_ROOT:[TCPWARE.EXAMPLES.RPC]GETSYI.X file provides a sample interface definition containing a structure.
Compile the RPCGEN output files, server procedures, and main program separately using the appropriate language compiler(s):
XDR: DEC C (VAX, Alpha and Integrity):
$ CC /STANDARD=RELAXED /WARNING=DISABLE=(IMPLICITFUNC) filename.C
ONC: VAX C:
$ CC filename.C
ONC: DEC C (VAX):
$ CC /STANDARD=VAXC filename.C
ONC: DEC C (Alpha and Integrity):
$ CC /STANDARD=VAXC /NOMEMBER_ALIGN /ASSUME=NOALIGN filename.C
FORTRAN (VAX):
$ FORTRAN filename.FOR
FORTRAN (Alpha and Integrity):
$ FORTRAN /NOALIGN /WARNING=(DECLARATIONS,ALIGN) filename.FOR
Link the object code files. Make sure you link in the ONC RPC RTL. Use the following command:
XDR: DEC C (VAX, Alpha and Integrity):
$ LINK filenames, SYS$INPUT /OPTIONS
UCX$RPCXDR_SHR /SHARE
SYS$SHARE:DECC$SHR /SHARE
Ctrl+Z
ONC: VAX:
$ LINK filenames, SYS$INPUT /OPTIONS
SYS$SHARE:VAXCRTL/SHARE
SYS$SHARE:TCPWARE_RPCLIB_SHR/SHARE
Ctrl+Z
ONC: Alpha and Integrity:
$ LINK filenames, SYS$INPUT /OPTIONS
UCX$RPCXDR_SHR /SHARE
SYS$SHARE:DECC$SHR /SHARE
Ctrl+Z
After entering the command, press Ctrl+Z.
To avoid repetitive data entry, you may create an OpenVMS command procedure to execute these commands.
The Port Mapper must be running on the server host. If it is not running, use the NETCU ADD SERVICE command to start it. See Chapter 2, NETCU Commands of the NETCU Command Reference manual for details on this command.
Perform these steps:
1. Run the server program interactively to debug it, or using the /DETACHED qualifier. Refer to the OpenVMS documentation for details.
2. Run the client main program.
ONC: ONC RPC provides two asynchronous transport protocols: TCPA and UDPA. These protocols allow you to write multi-threaded servers that can process multiple requests in parallel.
Only an asynchronous service can benefit from using an asynchronous transport.
For example, you would use an asynchronous transport for a service that performs a lot of asynchronous file I/O by issuing QIOs. You would not use an asynchronous transport for a service that performs a lot of synchronous file I/O.
Client processes cannot use TCPA and UDPA.
The asynchronous transport protocols are specific to TCPware.
The ONC RPC Fundamentals, Chapter 12, explains the differences between each transport protocol.
ONC: This section explains how to write an asynchronous server.
1. Decide how many threads the server will support. The number of threads determines the number of requests the server can handle in parallel. The server can parallel process as many requests as it has threads.
2. Choose the TCPA and/or UDPA transport protocol. (A server can support both.)
3. Determine:
· The size of the XID cache. Generally, this is at least the number of UDPA or TCPA threads.
· Which procedures, if any, the XID cache will contain responses for.
ONC: Write a program that performs the following steps:
1. To set up the server:
a. Call svcudpa_create and/or svctcpa_create for each thread. Save the return values for later use. Use the svc_getchan routine after the first call and specify the returned value in subsequent calls.
b. If you are enabling the XID cache, call svcudpa_enablecache and/or svctcpa_enablecache for each thread. Use the result of the first call to svcudpa_enablecache/svctcpa_enablecache as input to successive calls to that routine, so that all threads use the same cache.
c. Call the svc_register routine once for each transport to register the service.
2. Put the main code in "hibernation" by calling SYS$HIBER instead of svc_run. SYS$HIBER is an OpenVMS system service that accepts no input arguments.
3. To shut down the server:
a. Perform any shutdown steps that are specific to your server.
b. Call svctcpa_shutdown once for all TCPA threads.
c. Call svcudpa_shutdown once for all UDPA threads.
d. Call svc_destroy once for each thread.
ONC: Asynchronous transports use more memory than synchronous transports because each service has more than one thread.
When TCPA receives requests greater than 4Kbytes, it uses significantly more memory than TCP uses for the same size requests. TCP reads in 4Kbytes of data, processes the data, then reads more data as necessary. TCPA reads all of the data before calling the server dispatch routine.
ONC: All UDPA and TCPA servers use asynchronous system traps (ASTs). Refer to the Guide to VMS Programming Resources for complete information on ASTs.
When using ASTs, follow these guidelines:
· Do not permit the main program to disable ASTs for long periods of time. If the program disables ASTs before it calls SYS$HIBER, the server does not respond to requests.
· The AST quota for the server process must allow at least one AST for each thread.
· The dispatch routine is called as a user-mode AST. This means a program cannot do synchronous waiting when an AST is required to wake up the program.
· Only one AST can be active at a time.
RPCINFO is an ONC RPC utility that allows you to:
· Request a listing of all programs registered with a Port Mapper.
· Call the NULL routine of any program
RPCINFO supports both the UDP and TCP protocols.
To request a listing of all programs that are registered with the Port Mapper, enter the RPCINFO command in the following format at the DCL prompt:
RPCINFO -p [-u | -t][host-name]
-p |
Calls the Port Mapper. |
-u |
Uses the UDP transport to send the request. This is the default if you do not specify a transport. |
-t |
Uses the TCP transport to send the request. |
host-name |
Specifies the
domain name of the host on which the Port Mapper resides. |
$ rpcinfo -p hermes
Program Version
Protocol Port
------- ------- -------- ----
100000 2 udp 111 rpcbind
100000 2 tcp 111 rpcbind
100005 1 udp 2049 mountd
To call the NULL routine of a program, enter the RPCINFO command in the following format at the DCL prompt:
RPCINFO [-u | -t] host-name program[version]
-u |
Uses the UDP
transport to send the request. |
-t |
Uses the TCP transport to send the request. |
host-name |
Specifies the domain name of the target host. |
program |
Specifies the program number of the target program. |
Version |
Specifies the
version number of the target program. |
For example, suppose you enter the following command:
$ RPCINFO ETA 100000 2
The following message displays if the call completes successfully:
Version 2 of program 100000 successfully called