Linux RPC
Comer Chapter 21(RPCgen Concept)
RFC 1057 – RPC Spec.UNIX Network Programming - Stevens
1
Using Remote Procedure Calls
• As a program specification technique• For program specification and as an
abstraction during design• Explicitly in the implementation• For design and implementation, from scratch• For design and implementation, with
standard libraries• For automated implementation
2
RPC Programming MechanismsONC (Open Network Computing)
• XDR library routines for data conversion• XDR library routines for complex data
structures• RPC run-time library routines• Program generator tool
3
RPC Programming Process
• Dividing the program into local and remote procedures.
4
Proc A
Client Stub
Server Stub
Proc B
RPC
RPC Dispatching(Procedure Location)
5
Proc A1
Client Stub
Server Stub
Proc B1
Proc A2
Client StubProc B2
Server Stub
Dispatcher
RPC
RPC
RPC Interface Specification
6
Proc A
Client comm
Server Iface
Proc B
Server Comm
Client Iface
RPC
RPCgen Input and Output
• Input– Q.x Interface specification file
• Output– Q.h Declarations header file– Q_xdr.cpp XDR procedure calls used to
marshal arguments– Q_clnt.cpp Client-side communications stub– Q_svc.cpp Server-side communications stub
7
RPC Process Flow
8
Q.x rpcgen
Q_clnt.cpp
Q.h
Q_xdr.cpp
Q_svc.cpp
Clientapplication
Clientinterface
Serverinterface
Remoteprocedures
Server
Clientcompile
compile
RPC General Build Procedure
9
Develop Interface
Develop Client Develop Server
Developing the Interface
10
MyApp.x
RPCgen
MyApp_clnt.cClient Stub
MyApp_svc.cServer Stub
MyApp.h
MyApp_xdr.c
Developing the Server
11
MyApp.x
RPCgen
MyApp_svc.cServer Stub
MyApp.hMySrvr.c MyApp_xdr.c
C Compiler
Linker
MySrvr.exe
Developing the Client
12
MyApp.idl
RPCgen
MyApp_clnt.cClient Stub
MyApp.hMyClnt.c
C Compiler
Linker
MyClnt.exe
MyApp_xdr.c
How the Server Prepares for a Connection
• (Be certain that Portmap is running)• Create UDP service• Register UDP service with Portmap• Create TCP service• Register TCP service with Portmap• Run service...– Uses select( ) to monitor ports.
13
Start Portmap
Portmap is included in all Linux distributions as a standard server.
Under Red Hat Fedora Open services applet ,select portmap and startFrom command line (as root)
/sbin/services portmap start
Other distributions should be similar
14
Server concurrency mode
RPC servers can be created in either single threaded or multi-threaded mode.
Servers automatically create and (when done) destroy a thread for each incoming connection.
15
Register the Server Program
svc_register(port#, SERV#, VER#, serv_func, proto#);
port#: port on which the service is activeSERV#: unique number for the serviceVER#: version for this particular serviceserv_func: name by which this function is calledproto#: IPPROTO_UDP or IPPROTO_TCP
16
How the Client Establishes a Connection
• Make a Remote Procedure Call• Find the Server Host Computer• Find Server Process Port # (through Portmap)• Create a (connection) to the Server Process
17
How the Client Establishes a Connection
clnt_create(server, SERV#, VER#, proto#);
remote procedure call...
Clnt_destroy(CLIENT);
18
Example #1
• Temperature Server (Fahrenheit to Centigrade)– Parameters passed as integers– TCP / IP port connection
• Source files:– temp.x– Tclient.c– tempServer.c
19
temp.x
program TEMPSERV {version TEMPVERS {
int TempConv(int) = 1; //procedure number} = 1; //version number
} = 77; //program number
20
TClient.c#include <stdio.h>, <stdlib.h>, <string.h>#include <rpc/rpc.h>#include "temp.h"#define YES 0#define NO 1
void main (int argc, char *argv[]){
int tempconvert(int temp, char *srvr);int temperature, nuTemp;int loopFlag;char srvr[25];CLIENT * cl;
21
TClient.c (cont)
strcpy (srvr, argv[1]);cl = clnt_create(srvr, TEMPSERV, TEMPVERS, "tcp");loopFlag = YES;
while(loopFlag == YES){
printf("Enter temperature in Faherenheit (-999 to quit)");
scanf ("%d", &temperature);ans = tempconv_1(&temperature, cl);
22
TClient.c (cont)
if (ans != NULL)nuTemp = * ans;
if (temperature == -999 || temperature == -9999){
loopFlag = NO;printf ("Goodbye...\n");continue;
}printf("That’s %2d in centigrade\n", nuTemp);
}clnt_destroy(cl);return 0;
}
23
tempServer.c
#include <stdlib.h>, <unistd.h>, <stdio.h>#include <rpc/rpc.h>, "temp.h"
static int count;static int nuTemp;
int *tempconv_1_svc (int *val, struct svc_req * rqst)
{int oldTemp;oldTemp = *val;
24
tempServer.c
if (oldTemp == -9999){
printf("We're shutting down...\n");exit (0);
}printf("We got a temperature of %d, ", oldTemp);count++;nuTemp = (int)((5*(oldTemp -32)) / 9.0);printf("and we returned a value of %d\n", nuTemp);sleep(1);return (&nuTemp);
}
25
Files created with rpcgen
• Input:– temp.x
• Output– temp.h– temp_xdr.c (NULL file)– temp_clnt.c– temp_svc.c
26
temp.h#include <rpc/rpc.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TEMPSERV 77
#define TEMPVERS 1
#if defined(__STDC__) || defined(__cplusplus)
#define TempConv 1
extern int * tempconv_1(int *, CLIENT *);
extern int * tempconv_1_svc(int *, struct svc_req *);
extern int tempserv_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
#ifdef __cplusplus}
#endif
#endif /* !_TEMP_H_RPCGEN */
27
temp_xdr.c
#include <rpc/rpc.h>
#include "temp.h"
28
temp_clnt.c#include <memory.h> /* for memset */#include "temp.h“/* Default timeout can be changed using
clnt_control() */
static struct timeval TIMEOUT = { 25, 0 };
int *tempconv_1(int *argp, CLIENT *clnt){static int clnt_res;memset((char *)&clnt_res, 0, sizeof(clnt_res));
29
temp_clnt.c (cont)
if (clnt_call (clnt, TempConv,(xdrproc_t) xdr_int, (caddr_t)
argp, (xdrproc_t) xdr_int, (caddr_t) &clnt_res,TIMEOUT) != RPC_SUCCESS)
{return (NULL);
}return (&clnt_res);}
30
temp_svc.c
#include "temp.h“#include <stdio.h>#include <stdlib.h>#include <rpc/pmap_clnt.h>#include <string.h>#include <memory.h>#include <sys/socket.h>#include <netinet/in.h>
#ifndef SIG_PF#define SIG_PF void(*)(int)#endif
31
temp_svc.c (cont)static void tempserv_1(struct svc_req *rqstp, register SVCXPRT *transp){
union {
int tempconv_1_arg;
} argument;
char *result;
xdrproc_t _xdr_argument, _xdr_result;
char *(*local)(char *, struct svc_req *);
switch (rqstp->rq_proc) {
case NULLPROC:
(void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);return;
case TempConv:
_xdr_argument = (xdrproc_t) xdr_int;
_xdr_result = (xdrproc_t) xdr_int;
local = (char *(*)(char *, struct svc_req *)) tempconv_1_svc;break;
default:
svcerr_noproc (transp);
return; }32
temp_svc.c (cont)memset ((char *)&argument, 0, sizeof (argument));if (!svc_getargs (transp, (xdrproc_t) _xdr_argument,
(caddr_t) &argument)) {svcerr_decode (transp);return;
}result = (*local)((char *)&argument, rqstp);if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
svcerr_systemerr (transp);}if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
fprintf (stderr, "%s", "unable to free arguments");exit (1);
}return;
}
33
temp_svc.c (cont)int main (int argc, char **argv){
register SVCXPRT *transp;pmap_unset (TEMPSERV, TEMPVERS);transp = svcudp_create(RPC_ANYSOCK);if (transp == NULL) {
fprintf (stderr, "%s", "can’t create udp service."); exit(1);}if (!svc_register(transp, TEMPSERV, TEMPVERS,
tempserv_1, IPPROTO_UDP)) {fprintf (stderr, "%s", "unable to register
(TEMPSERV, TEMPVERS, udp).");exit(1);
}
34
temp_svc.c (cont)transp = svctcp_create(RPC_ANYSOCK, 0, 0);
if (transp == NULL) {fprintf (stderr, "%s", "cannot create
tcp service.");
exit(1);}if (!svc_register(transp, TEMPSERV, TEMPVERS,
tempserv_1, IPPROTO_TCP)) {fprintf (stderr, "%s", "unable to
register (TEMPSERV, TEMPVERS, tcp).");
exit(1);}svc_run ();fprintf (stderr, "%s", "svc_run returned");exit (1); /* NOTREACHED */}
35
Sample Client Output
D:\data\RPC\onrpc_temp\client\Debug>client localhost
Enter the temperature in Faherenheit (-999 to quit)32
That would be 0 in centigrade
Enter the temperature in Faherenheit (-999 to quit)100
That would be 37 in centigrade
Enter the temperature in Faherenheit (-999 to quit)212
That would be 100 in centigrade
Enter the temperature in Faherenheit (-999 to quit)-9999
Goodbye...
D:\data\RPC\onrpc_temp\client\Debug>
36
Sample Server Output
D:\data\RPC\examples\onrpc_temp\server\Debug>server
We got a temperature of 32, and we returned a value of 0
We got a temperature of 100, and we returned a value of 37
We got a temperature of 212, and we returned a value of 100
We're shutting down...
D:\data\RPC\examples\onrpc_temp\server\Debug>
37
Summary
• Linux RPC Implementation models SUN ONCRPC functionality
• RPC specific programming limited to linking original applications code with rpcgen interface code.
38
Top Related