1 / 38

Linux RPC

Linux RPC. Comer Chapter 21 (RPCgen Concept) RFC 1057 – RPC Spec. UNIX Network Programming - Stevens. Using Remote Procedure Calls. As a program specification technique For program specification and as an abstraction during design Explicitly in the implementation

audra-velez
Download Presentation

Linux RPC

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Linux RPC Comer Chapter 21 (RPCgen Concept) RFC 1057 – RPC Spec. UNIX Network Programming - Stevens

  2. 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

  3. 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

  4. RPC Programming Process • Dividing the program into local and remote procedures. RPC Proc A Server Stub Client Stub Proc B

  5. RPC Dispatching(Procedure Location) RPC Proc A2 Dispatcher Proc A1 RPC Server Stub Server Stub Client Stub Client Stub Proc B1 Proc B2

  6. RPC Interface Specification Proc A Server Comm RPC Client Iface Server Iface Client comm Proc B

  7. 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

  8. RPC Process Flow Client application Client interface Q_clnt.cpp compile Client Q.h rpcgen Q.x Q_xdr.cpp compile Server Q_svc.cpp Remote procedures Server interface

  9. RPC General Build Procedure Develop Interface Develop Client Develop Server

  10. Developing the Interface MyApp.x RPCgen MyApp_clnt.c Client Stub MyApp.h MyApp_svc.c Server Stub MyApp_xdr.c

  11. Developing the Server MyApp.x RPCgen MySrvr.c MyApp_xdr.c MyApp.h C Compiler MyApp_svc.c Server Stub Linker MySrvr.exe

  12. Developing the Client MyApp.idl RPCgen MyClnt.c MyApp_xdr.c MyApp.h C Compiler MyApp_clnt.c Client Stub Linker MyClnt.exe

  13. 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.

  14. Start Portmap Portmap is included in all Linux distributions as a standard server. Under Red Hat Fedora Open services applet ,select portmap and start From command line (as root) /sbin/services portmap start Other distributions should be similar

  15. 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.

  16. Register the Server Program svc_register(port#, SERV#, VER#, serv_func, proto#); port#: port on which the service is active SERV#: unique number for the service VER#: version for this particular service serv_func: name by which this function is called proto#: IPPROTO_UDP or IPPROTO_TCP

  17. 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

  18. How the Client Establishes a Connection clnt_create(server, SERV#, VER#, proto#); remote procedure call... Clnt_destroy(CLIENT);

  19. Example #1 • Temperature Server (Fahrenheit to Centigrade) • Parameters passed as integers • TCP / IP port connection • Source files: • temp.x • Tclient.c • tempServer.c

  20. temp.x program TEMPSERV { version TEMPVERS { intTempConv(int) = 1; //procedure number } = 1; //version number } = 77; //program number

  21. 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;

  22. 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);

  23. 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; }

  24. 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;

  25. 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); }

  26. Files created with rpcgen • Input: • temp.x • Output • temp.h • temp_xdr.c (NULL file) • temp_clnt.c • temp_svc.c

  27. 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 *, structsvc_req *); extern int tempserv_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #ifdef __cplusplus} #endif #endif /* !_TEMP_H_RPCGEN */

  28. temp_xdr.c #include <rpc/rpc.h> #include "temp.h"

  29. temp_clnt.c #include <memory.h> /* for memset */ #include "temp.h“ /* Default timeout can be changed using clnt_control() */ static structtimeval TIMEOUT = { 25, 0 }; int *tempconv_1(int *argp, CLIENT *clnt){ static intclnt_res; memset((char *)&clnt_res, 0, sizeof(clnt_res));

  30. 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);}

  31. 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

  32. temp_svc.c (cont) static void tempserv_1(structsvc_req *rqstp, register SVCXPRT *transp){ union { int tempconv_1_arg; } argument; char *result; xdrproc_t _xdr_argument, _xdr_result; char *(*local)(char *, structsvc_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 *, structsvc_req *)) tempconv_1_svc; break; default: svcerr_noproc (transp); return; }

  33. 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; }

  34. temp_svc.c (cont) int main (intargc, 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); }

  35. 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 */}

  36. 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>

  37. 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>

  38. Summary • Linux RPC Implementation models SUN ONCRPC functionality • RPC specific programming limited to linking original applications code with rpcgen interface code.

More Related