RPC Part 3

25
RPC Part 3 More Linux RPC

description

RPC Part 3. More Linux RPC. Add RPC program. Objectives: Pass multiple arguments from calling program to remote procedure Support multiple procedures within a single interface Files: add.x - interface definition add.h - rpegen header file add_xdr.c - rpcgen data representation file - PowerPoint PPT Presentation

Transcript of RPC Part 3

Page 1: RPC Part 3

RPC Part 3

More Linux RPC

Page 2: RPC Part 3

Add RPC programObjectives:• Pass multiple arguments from calling program to remote

procedure• Support multiple procedures within a single interface

• Files:– add.x - interface definition

• add.h - rpegen header file• add_xdr.c - rpcgen data representation file• add_clnt.c - rpcgen client stub code• add_svc.c - rpcgen remote procedures

– addClient.c - client application code– addServer.c - remote procedure code– client_intfce.c - interface code between app and rpcgen code

UMKC - CSTP CS423 2

Page 3: RPC Part 3

Add

UMKC - CSTP CS423 3

add.x rpcgen

add_clnt.c

add.h

add _xdr.c

add _svc.c

addClient.c Client_intfce.c

addServer.c

Server.exe

Client.execompile

compile

Page 4: RPC Part 3

Add (add.x interface specification)

program ADDSERV {version ADDVERS {

int addFunc(struct numtype) = 1;void myshutdown(void) = 2;

} = 1;} = 9876;

struct numtype{

int int1;int int2;int int3;

};

UMKC - CSTP CS423 4

Page 5: RPC Part 3

Add (program file linkages)

UMKC - CSTP CS423 5

addClient.c

add_clnt.c addServer.c

add_svc.cRPC

add_xdr.c add.h

Page 6: RPC Part 3

Add (addClient.c) 1Add (addClient.c) 1#include <stdio.h>#include <stdlib.h>#include <string.h>#include <rpc/rpc.h>#include "add.h"

#define YES 0#define NO 1char srvr[25];void myshutdown ();int addfunc (int num1, int num2, int num3);

int main (int argc, char *argv[]){

int num1, num2, num3, result;int loopFlag;char ans, dummy;

Page 7: RPC Part 3

Add (addClient.c) 2Add (addClient.c) 2if (argc != 2) {

fprintf(stderr, "usage: %s host\n", argv[0]);exit (1);

}strcpy (srvr, argv[1]);

loopFlag = YES;

while(loopFlag == YES){

printf("Enter 3 numbers to add ");scanf ("%d%d%d%c", &num1, &num2, &num3, &dummy);result = addfunc (num1, num2, num3);printf ("The sum of those numbers is %d\n", result);

Page 8: RPC Part 3

Add (addClient.c) 3Add (addClient.c) 3printf ("Do you want to do another calculation (y or n)? ");

scanf ("%c%c", &ans, &dummy);if (ans != 'y' && ans != 'Y'){

loopFlag = NO;printf ("Goodbye...\n");if (ans == 'Z'){

myshutdown ();}continue;

}// end-of-if}//end-of-while

return 0;}

Page 9: RPC Part 3

Add (addClient.c) 4Add (addClient.c) 4

int addfunc (int num1, int num2, int num3) {

CLIENT *cl;int *result;struct numtype nums;cl = clnt_create(srvr, ADDSERV, ADDVERS, "tcp");if (cl == NULL) {

printf("Couldn't create client\n");exit (1);

}nums.int1 = num1;nums.int2 = num2;nums.int3 = num3;result = addfunc_1(&nums, cl);clnt_destroy(cl);return (*result);

}

Page 10: RPC Part 3

Add (addClient.c) 5Add (addClient.c) 5void myshutdown (){

CLIENT *cl;void *dummy;cl = clnt_create(srvr, ADDSERV, ADDVERS, "tcp");if (cl == NULL) {

printf("Couldn't create client\n");exit (1);

}myshutdown_1(dummy, cl);clnt_destroy(cl);

}

Page 11: RPC Part 3

Add (addServer.c)

#include <stdlib.h>

#include <stdio.h>

#include <unistd.h>

#include <rpc/rpc.h>

#include "add.h"

static int sum;

int *addfunc_1_svc (numtype *nums, struct svc_req *data){

int nuint1, nuint2, nuint3;

nuint1 = nums->int1;

nuint2 = nums->int2;

nuint3 = nums->int3;

UMKC - CSTP CS423 11

Page 12: RPC Part 3

Add (addServer.c)

printf("We got numbers %d, %d, and %d. ",nuint1,nuint2,nuint3);

sum = nuint1 + nuint2 + nuint3;printf("and the sum is %d\n", sum);sleep(1);return (&sum);

}

void *myshutdown_1_svc (void *dummy, struct svc_req *data){

printf ("Shutting down server....\n");exit (0);

}

UMKC - CSTP CS423 12

Page 13: RPC Part 3

Add (program file linkages)

UMKC - CSTP CS423 13

addClient.c

add_clnt.c

addServer.c

add_svc.cRPC

add_xdr.c add.h

Page 14: RPC Part 3

Add.h (RPCgen)#ifndef _ADD_H_RPCGEN#define _ADD_H_RPCGEN#include <rpc/rpc.h>

extern "C" {struct numtype {

int int1;int int2;int int3;

};typedef struct numtype numtype;#define ADDSERV 9876#define ADDVERS 1

UMKC - CSTP CS423 14

Page 15: RPC Part 3

Add.h (RPCgen)#if defined(__STDC__) || defined(__cplusplus)

#define addfunc 1extern int * addfunc_1(struct numtype *, CLIENT *);extern int * addfunc_1_svc(struct numtype *, struct svc_req *);

#define myshutdown 2extern void * myshutdown_1(void *, CLIENT *);extern void * myshutdown_1_svc(void *, struct svc_req *);extern int addserv_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);/* the xdr functions */extern bool_t xdr_numtype (XDR *, numtype*);#endif

UMKC - CSTP CS423 15

Page 16: RPC Part 3

Add (add_xdr.c)

#include "add.h“

bool_t xdr_numtype (XDR *xdrs, numtype *objp){

register int32_t *buf;

if (!xdr_int (xdrs, &objp->int1)) return FALSE;

if (!xdr_int (xdrs, &objp->int2)) return FALSE;

if (!xdr_int (xdrs, &objp->int3)) return FALSE;

return TRUE;}

UMKC - CSTP CS423 16

Page 17: RPC Part 3

Add (add_clnt.c)

#include <memory.h> #include "add.h“/* Default timeout can be changed using clnt_control() */static struct timeval TIMEOUT = { 25, 0 };

int *addfunc_1(struct numtype *argp, CLIENT *clnt){

static int clnt_res;memset((char *)&clnt_res, 0, sizeof(clnt_res));if (clnt_call (clnt, addfunc,

(xdrproc_t) xdr_numtype, (caddr_t) argp,(xdrproc_t) xdr_int, (caddr_t) &clnt_res,TIMEOUT) != RPC_SUCCESS)

{return (NULL);

}return (&clnt_res);

}UMKC - CSTP CS423 17

Page 18: RPC Part 3

Add (add_clnt.c)

void *myshutdown_1(void *argp, CLIENT *clnt)

{

static char clnt_res;

memset((char *)&clnt_res, 0, sizeof(clnt_res));

if (clnt_call (clnt, myshutdown, (xdrproc_t) xdr_void, (caddr_t) argp, (xdrproc_t) xdr_void, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS)

{

return (NULL);

}

return ((void *)&clnt_res);}

UMKC - CSTP CS423 18

Page 19: RPC Part 3

Add (add_svc.c)

#include "add.h“ <stdio.h> <stdlib.h> <rpc/pmap_clnt.h>#include <string.h> <memory.h> <sys/socket.h> <netinet/in.h>#ifndef SIG_PF#define SIG_PF void(*)(int)#endifstatic void addserv_1(struct svc_req *rqstp, register SVCXPRT *transp){

union {struct numtype addfunc_1_arg;

} argument;char *result;xdrproc_t _xdr_argument, _xdr_result;char *(*local)(char *, struct svc_req *);

UMKC - CSTP CS423 19

Page 20: RPC Part 3

Add (add_svc.c)

switch (rqstp->rq_proc) {case NULLPROC: svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return;case addfunc:

_xdr_argument = (xdrproc_t) xdr_numtype; _xdr_result = (xdrproc_t) xdr_int; local = (char *(*)(char *, struct svc_req *))

addfunc_1_svc; break;case myshutdown:

_xdr_argument = (xdrproc_t) xdr_void; _xdr_result = (xdrproc_t) xdr_void; local= (char *(*)(char *,struct svc_req

*))myshutdown_1_svc; break;default:

svcerr_noproc (transp);return;

}

UMKC - CSTP CS423 20

Page 21: RPC Part 3

Add (add_svc.c)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;

}

UMKC - CSTP CS423 21

Page 22: RPC Part 3

Add (add_svc.c)

int main (int argc, char **argv){

register SVCXPRT *transp;pmap_unset (ADDSERV, ADDVERS);transp = svcudp_create(RPC_ANYSOCK);if (transp == NULL) { fprintf (stderr, "%s", "cannot create udp service.");

exit(1);}if (!svc_register(transp, ADDSERV, ADDVERS, addserv_1, IPPROTO_UDP))

{ fprintf (stderr,"%s", "unable to register(ADDSERV, ADDVERS, udp)"); exit(1);}

UMKC - CSTP CS423 22

Page 23: RPC Part 3

Add (add_svc.c)

transp = svctcp_create(RPC_ANYSOCK, 0, 0);if (transp == NULL)

{fprintf (stderr, "%s", "cannot create tcp service.");exit(1);

}if (!svc_register(transp, ADDSERV, ADDVERS, addserv_1, IPPROTO_TCP))

{ fprintf (stderr, "%s","unable to register (ADDSERV,ADDVERS,tcp)"); exit(1);}svc_run ();

fprintf (stderr, "%s", "svc_run returned");exit (1);/* NOTREACHED */

}

UMKC - CSTP CS423 23

Page 24: RPC Part 3

Add results

D:\data\RPC\examples\add2>client localhostEnter 3 numbers to add 123 09 8765The sum of those numbers is 8897Do you want to do another calculation (y or n)? ZGoodbye...D:\data\RPC\examples\add2>

D:\data\RPC\examples\add2>serverWe got numbers 123, 9, and 8765. and the sum is 8897Shutting down server....D:\data\RPC\examples\add2>

UMKC - CSTP CS423 24

Page 25: RPC Part 3

Summary• The objective of RPC (including ONCRPC) is to provide a

way to access remote procedures in a way that does not require knowledge of inter-machine communications.

• ONCRPC supports the core capabilities of SUN ONC RPC• ONCRPC uses sockets as the underlying platform for

supporting RPC• ONCRPC supports:

– Multiple interfaces on a single machine– Multiple versions of a single interface– Multiple functions (remote procedures) within a single interface

UMKC - CSTP CS423 25