I. Overview
In traditional programming concepts, a process is compiled locally by a programmer and can only be limited to a piece of code that runs locally, and that is, the running relationship between its main program and the process is the local call relationship. Therefore, this kind of structure has been unable to meet the actual demand today in the growing network. In a word, the traditional process call pattern cannot make full use of the resources of other hosts on the network (such as CPU, memory, etc.), nor can it improve the sharing of the code between entities, which makes the host resources waste. |
In this paper, RPC programming is a good solution to the traditional process of a series of abuses. RPC allows us to take advantage of a multiprocessor environment that is not shared memory (for example, multiple workstations connected over a LAN), so that you can easily distribute your application across multiple workstations, as if the application were running on a multiprocessor computer. You can easily realize the process code sharing, improve the utilization of the system resources, can also be a large number of operations on the processing capacity of a strong system to run, so as to reduce the burden of front-end machines. |
Second, the structure principle of RPC and its calling mechanism |
As mentioned in the previous RPC is a C/S programming mode, a bit similar to C/S Socket programming mode, but it is higher than the layer. When we set up the RPC service, the client's invocation parameters pass through the underlying RPC transport channel, either UDP or TCP (also known as ti-rpc-), and go to the appropriate RPC application based on the destination address provided before the transfer and the RPC upper application number Porgramme Server, and the client at this point is waiting until a reply or time out timeout signal is received. The detailed flowchart is shown in Figure 1. When the server side obtains the request message, it performs the appropriate action and returns the result to the client according to the routine entry address of the RPC system when the RPC is registered.
When an RPC call completes, the corresponding thread sends the corresponding signal, and the client program continues to run.
Of course, a service host can have multiple remote procedures to provide services, so how to represent a single existing remote process. A remote procedure has three elements to uniquely determine: program number, version number, and procedure number. A program number is a remote procedure that distinguishes a group of related and unique procedure numbers. A program can have one or several different versions, and each version of the program contains a series of processes that can be invoked remotely, with the introduction of a version that allows RPC to be serviced at the same time in different versions. Each version contains a number of procedures that are available for remote invocation, and each process has its own uniquely marked procedure number. |
Third, RPC based application system development |
With the above introduction to the RPC principle, we will continue to discuss how to develop an application system based on RPC. In general, when developing RPC, we are typically divided into three steps: |
A, define the communication protocol that describes the client/server. |
The communication protocol here refers to the definition of the name of the service procedure, the data type of the calling parameter and the data type of the return parameter, including the underlying transport type (either UDP or TCP) or, of course, the automatic selection of the connection type by the RPC underlying function to establish TI-RPC. The simplest method of protocol generation is to use the Protocol compilation tool, which is commonly used with Rpcgen, and I will describe it in detail in a later instance. |
b, develop client programs. |
C, the development of server-side programs. |
When developing client and server-side programs, RPC provides us with different levels of development routines calling interfaces. Different levels of interface provide varying degrees of control over RPC. Generally can be divided into 5 levels of programming interface, and then we discuss each layer provided by the functional functions. |
The simple layer, designed for the rapid development of RPC application services, is intended for general RPC applications, and provides the following functional functions. |
The name of the function |
Function description |
Rpc_reg () |
Registers a procedure on a specific type of transport layer as the RPC program that provides the service |
Rpc_call () |
Remote invocation of a procedure specified on a specified host |
Rpc_broadcast () |
Broadcasts a remote procedure call request to all transport ports of the specified type |
|
At this level, the program needs to create a client handle before making the call request, or establish a server-side handle before listening for the request. In this layer, the program is free to bind its application to all transport ports, which provides the following functional functions. |
The name of the function |
Function description |
Clnt_create () |
This function is invoked by the program to tell the location of the underlying RPC server and its transport type |
Clnt_create_timed () |
Defines the maximum time to timeout for each attempt to connect |
Svc_create () |
Creates a server handle on a transport port of the specified type, telling the corresponding entry address of the underlying RPC event procedure |
Clnt_call () |
Issuing an RPC call request to the server side |
|
The middle tier provides a more detailed RPC control interface to the program, and this layer of code becomes more complex, but runs more efficiently, providing the following functional functions. |
The name of the function |
Function description |
Clnt_tp_create () |
To establish a client handle on the specified transport port |
Clnt_tp_create_timed () |
Define Maximum transmission delay |
Svc_tp_creaet () |
Establish a service handle on the specified transport port |
Clnt_call () |
Issuing RPC call requests to the server side |
|
This layer provides a number of transport-related function calls, which provide the following functional functions. |
Function name |
Feature description |
Clnt_tli_create () |
Establishes a client handle on the specified transport port |
Svc_tli_create () |
Establish a service handle on the specified transport port |
Rpcb_set () |
Map RPC Services and network addresses by calling Rpcbind |
Rpcb_unset () |
Delete the mapping relationship built by Rpcb_set () |
Rpcb_getaddr () |
Call Rpcbind will specify the transport address for the RPC service |
Svc_reg () |
Associates the specified program and version number with the corresponding time routine |
Svc_ureg () |
Delete the association built by Svc_reg () |
Clnt_call () |
Client initiates RPC request to the specified server side |
|
5, the underlying routine |
This layer provides all the calling interfaces that control the transport options, which provides the following functional functions. |
The name of the function |
Function description |
Clnt_dg_create () |
Establish client handles to remote procedures on the client with no connection |
Svc_dg_create () |
Establishing a service handle with no connection |
Clnt_vc_create () |
Establish a client handle in a connection-oriented manner |
Svc_vc_create () |
Establishing RPC service handles in a connection-oriented manner |
Clnt_call () |
The client sends the call request to the server side |
Iv. Introduction of examples
I'll introduce you to the reader through an example of a simple layer RPC implementation. Usually in this process we
The RPC Protocol compilation tool-rpcgen will be used. The Rpcgen tool is used to generate the remote Program Interface module, which will be RPC
The source code for language writing is compiled, and the RPC language is similar in structure and syntax to the C language. Compiled by Rpcgen
C source program can be compiled directly with the C compiler, so the entire compilation work will be divided into two parts. Rpcgen
The source program ends with. x, and the following file is generated through its compilation:
A a header file (. h) Includes descriptions of server and client program variables, constants, types, and so on.
B A series of XDR routines that can be handled by the data types defined in the header file.
c) A standard procedural framework on the server side.
D) A client-side standard program framework.
Of course, these outputs can be selective, and the Rpcgen compilation options are described below:
Options feature
'-' a generates all the template files
'-' Sc generate template file for client
'-' Ss generate server-side template files
'-' Sm generates makefile files
(See Solaris Rpcgen manaul for details)
Rpcgen source program time.x:
/* Time.x:remote Time Printing protocol * *
Program Timeprog {
Version Printimevers {
String Printime (string) = 1;
} = 1;
} = 0x20000001;
TIME_PROC.C source program:
/* Time_proc.c:implementation of the remote procedure "Printime" * *
#include <stdio.h>
#include <rpc/rpc.h>/* Always needed * *
#include "time.h"/* time.h would be generated by Rpcgen * *
#include <time.h>
* Remote version of "Printime" * *
char * * printime_1 (char **msg,struct svc_req *req)
{
static char * result; /* Must be static! */
static Char tmp_char[100];
time_t Rawtime;
FILE *f;
f = fopen ("/tmp/rpc_result", "A +");
if (f = = (FILE *) NULL) {
strcpy (Tmp_char, "Error");
result = Tmp_char;;
return (&result);
}
fprintf (F, "%s", *msg); Used for debugging
Fclose (f);
Time (&rawtime);
sprintf (Tmp_char, "Current time is:%s", CTime (&rawtime));
Result =tmp_char;
return (&result);
}
RTIME.C Source Code
/*
* Rtime.c:remote Version
* "PRINTIME.C"
*/
#include <stdio.h>
#include "time.h"/* time.h generated by Rpcgen * *
Main (int argc, char **argv)
{
CLIENT *clnt;
Char *result;
Char *server;
Char *message;
if (argc!= 3) {
fprintf (stderr, "Usage:%s host message", Argv[0]);
Exit (1);
}
Server = argv[1];
message = Argv[2];
/*
* Create Client "handle" used for
* Calling Timeprog on the server
* Designated on the command line.
*/
CLNT = clnt_create (server, Timeprog, printimevers, "visible");
if (clnt = = (CLIENT *) NULL) {
/*
* couldn ' t establish connection
* with server.
* Print error message and die.
*/
Clnt_pcreateerror (server);
Exit (1);
}
/*
* Call the remote procedure
* "Printime" on the server
*/
Result =*printime_1 (&MESSAGE,CLNT);
if (result== (char *) NULL) {
/*
* An error occurred while calling
* The server.
* Print error message and die.
*/
Clnt_perror (clnt, server);
Exit (1);
}
/* Okay, we successfully called
* The remote procedure.
*/
if (strcmp (result, "Error") = = 0) {
/*
* Server is unable to print
* The time.
* Print error message and die.
*/
fprintf (stderr, "%s:could not get", argv[0]);
Exit (1);
}
printf ("From the time Server ...%s", result);
Clnt_destroy (CLNT);
Exit (0);
}
With the above three pieces of code, the RPC protocol can be compiled using the Rpcgen compilation tool, which commands the following:
$rpcgen time.x
Rpcgen will automatically generate Time.h, TIME_SVC.C, time_clnt.c
C is compiled using GCC provided by the system, and commands are as follows:
$GCC rtime.c time_clnt.c-o RTIME-LNSL//Client compilation
$GCC time_proc.c time_svc.c-o time_server-lnsl//