remote procedure call - york university · cosc3213 m. aboelaze yu fall 2002 rpc • the procedure...

40
COSC3213 M. Aboelaze YU Fall 2002 Remote Procedure Call York University COSC4213

Upload: buithien

Post on 10-Nov-2018

214 views

Category:

Documents


0 download

TRANSCRIPT

COSC3213 M. Aboelaze

YUFall 2002

Remote Procedure Call

York UniversityCOSC4213

COSC3213 M. Aboelaze

YUFall 2002

RPC

• The procedure is running on a different machine than the calling program

1. The server registers its services (procedures) with the portmapper.

2. The client contacts the portmapper to determine if the requested service (procedure) is available; and if so, on which port.

3. The client contacts the server to initiate service.

COSC3213 M. Aboelaze

YUFall 2002

RPC

• Network communication is hidden by procedure calls.

• Procedures may be executed on different hosts.

• The RPC mechanism hides the details. • A programmer decides which procedures are

executed, and where (on which hosts). • To make the details transparent, a remote

procedure call should be as much like a local call as possible.

COSC3213 M. Aboelaze

YUFall 2002

RPC

• Some issues we have to address– Data representation (could be different on the

2 machines).– Reliability (at most one, at least one, exact

one).– RPC uses at least once if it receives a reply, and

zero or more if no reply– XDR eXternal Data Representation is used as a

standard way to represent data when you send it to another machine

COSC3213 M. Aboelaze

YUFall 2002

RPC

• XDR specifies data formats for most of the data types clients and server exchange

• Examples are int (32 bit integer), unsigned int, hyper (64 bit signed binary number), float (32 bits), double (64 bits), string, fixed array, and structure.

• XDR allows the programmer to compose aggregate types from other types.

COSC3213 M. Aboelaze

YUFall 2002

RPC

• Implicit Types– XDR specifies the encoding of the data, but

does not support any information to specify its type.

– For example, int is encoded as big-endian with 32 bits, but no indication that this 32 bits are an int

– Client and server must agree on the exact format of the message they exchange

COSC3213 M. Aboelaze

YUFall 2002

RPC• Software support• Routines for conversion• Programmer creates an

XDR streams and appends data to it

• TO create a stream• Then append to it an int• Examples xdr_u_int,

xdr_short, xdr_float

#include <rpc/xdr.h>#define BUFFSIZE 4000

XDR *xdrs /*pointer to XDR stream*/

Char buf[MAXSIZE]

Xdrmem_create(xdrs, buf, BUFSIZE, XDR_ENCODE);

Thenint i;i=260;

xdr_int(xdrs, &i);

COSC3213 M. Aboelaze

YUFall 2002

Example

• Example on a dictionary program• First, a regular program is written

and tested• Once the program is tested, we can

change it into an RPC type.

COSC3213 M. Aboelaze

YUFall 2002

Example (regular program)/* dict.c - main, initw, nextin, insertw, deletew, lookupw */

#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <string.h>

#define MAXWORD 50 /* maximum length of a command or word */#define DICTSIZ 100 /* maximum number of entries in diction.*/char dict[DICTSIZ][MAXWORD+1];/*storage for a dictionary of words*/int nwords = 0; /* number of words in the dictionary */

int nextin(char *cmd, char *word), initw(), insertw(const char *word), deletew(const char *word), lookupw(const char *word);

/*--------------------------------------------------------------* main - insert, delete, or lookup words in a dictionary as

specified*-----------------------------------------------------------------*/

COSC3213 M. Aboelaze

YUFall 2002

Example (regular program)Int main(int argc, char argv[])

{char word[MAXWORD+1]; /* space to hold word from input line*/char cmd;int wrdlen; /* length of input word */

while (1) {wrdlen = nextin(&cmd, word);if (wrdlen < 0)

exit(0);switch (cmd) {case 'I': /* "initialize" */

initw();printf("Dictionary initialized to empty.\n");break;

case 'i': /* "insert" */insertw(word);printf("%s inserted.\n",word);break;

case 'd': /* "delete" */if (deletew(word))

printf("%s deleted.\n",word);else

printf("%s not found.\n",word);break;

COSC3213 M. Aboelaze

YUFall 2002

Example (regular program)case 'l': /* "lookup" */

if (lookupw(word))printf("%s was found.\n",word);

elseprintf("%s was not found.\n",word);

break;case 'q': /* quit */

printf("program quits.\n");exit(0);

default: /* illegal input */printf("command %c invalid.\n", cmd);break;

}}

}

COSC3213 M. Aboelaze

YUFall 2002

Example (regular program)/*-------------------------------------------------------------------

* nextin - read a command and (possibly) a word from the next input line*-------------------------------------------------------*/

int nextin(char *cmd, char *word){

int i, ch;

ch = getc(stdin);while (isspace(ch)) ch = getc(stdin);if (ch == EOF) return -1;*cmd = (char) ch; ch = getc(stdin);while (isspace(ch)) ch = getc(stdin);if (ch == EOF) return -1;if (ch == '\n') return 0;i = 0;while (!isspace(ch)) {

if (++i > MAXWORD) {printf("error: word too long.\n");exit(1);

}*word++ = ch;ch = getc(stdin);

}*word=‘\0’; return i;

}

COSC3213 M. Aboelaze

YUFall 2002

Example (regular program)/*------------------------------------------------------------------------

* initw - initialize the dictionary to contain no words at all*------------------------------------------------------------------------*/

intinitw(){

nwords = 0;return 1;

}

/*------------------------------------------------------------------------* insertw - insert a word in the dictionary*------------------------------------------------------------------------*/

intinsertw(const char *word){

strcpy(dict[nwords], word);nwords++;return nwords;

}

COSC3213 M. Aboelaze

YUFall 2002

Example (regular program)/*------------------------------------------------------------------------

* deletew - delete a word from the dictionary*------------------------------------------------------------------*/

int deletew(const char *word){

int i;

for (i=0 ; i<nwords ; i++)if (strcmp(word, dict[i]) == 0) {

nwords--;strcpy(dict[i], dict[nwords]);return 1;

}return 0;

}/*------------------------------------------------------------------------* lookupw - look up a word in the dictionary*------------------------------------------------------------------------*/

int lookupw(const char *word){

int i;

for (i=0 ; i<nwords ; i++)if (strcmp(word, dict[i]) == 0)

return 1;return 0;

}

COSC3213 M. Aboelaze

YUFall 2002

Dividing the program into local and remote procedures

• Moving one or more procedure to a remote machine require some changes.

• On the client side, we need some code to marshal the arguments and translate them into a machine-independent representation (XDR), and translate back the returned results to the machine rep.

• We also need some code on the procedure side to translate XDR machine XDR

COSC3213 M. Aboelaze

YUFall 2002

Dividing the program into local and remote procedures

• This is implemented as 2 stub procedures

Program 1

Client stub

Server stub

Procedure ARPC CALL

Machine A Machine B

COSC3213 M. Aboelaze

YUFall 2002

Dividing the program into local and remote procedures

• The previous case was for a very simple program with only one remote procedure.

• In general, we can have more than one procedure running on a remote machine.

• The remote program consists of a single server process that must be running before any call to it.

• An RPC must specify the address of the machine, and the name of the procedure running on this machine.

• The server program consists of a dispatcher and the procedures.

• The dispatcher send the call to the intended procedure.

COSC3213 M. Aboelaze

YUFall 2002

Dividing the program into local and remote procedures

• One way to make the transition from a single conventional program to a distributed one is to use the same name of the procedures for the stub procedure on the caller machine

• Program A calls procedure B in a conventional program.

• If we names the stub procedure on the client side B, and it has the same interface as the procedure B, we may even run the program without recompiling A (just link it with the stub named B).

COSC3213 M. Aboelaze

YUFall 2002

Rpcgen

• rpcgen reads an input file contains a specification of a remote program.

• It generates four output files, each contain source code.

• If the input file is Q.x, the output files are as follows

COSC3213 M. Aboelaze

YUFall 2002

Rpcgen• File Name• Q.h

• Q-xdr.c

• Q_clnt.c

• Q_scv.c

• Contents• Decleration of constants used

for both client and server• XDR procedure calls to

marshal arguments

• Client side communication stub

• Server side communication stub

COSC3213 M. Aboelaze

YUFall 2002

Client application

Q.x rpcgen

Q_clnt.c

Q.h

Q_xdr.c

Q_svc.c

C compiler

C compiler

Client

Server

Remote procedures

COSC3213 M. Aboelaze

YUFall 2002

Eight Steps to Distributed Application

1. Build and test a conventional application2. Divide the program by choosing a set of procedures to move to a

remote machine3. Write an rpcgen specification for the remote program, including

names and numbers for the remote procedures and the declaration of their arguments.

4. Run the rpcgen to check the specifications (will generate 4 files).5. Write stub interface for client and server (application program

and 3 files generated by rpcgen)6. Compile and link together the client program (remote procedures

and 3 files generated by rpcgen)7. Compile and link together the server program8. Start the server on the remote machine and then client on local

COSC3213 M. Aboelaze

YUFall 2002

Step 1

• Build and test a conventional algorithm

• Done in the previous slides.

COSC3213 M. Aboelaze

YUFall 2002

Step 2

• Divide the program into a set of procedures to be executed on a remote machine

• The original program

main

nextin

insertw

initw

deletew

lookupw

COSC3213 M. Aboelaze

YUFall 2002

Step 2

• Division of the dictionary programComputer 1 Computer 2

main nextin

insertw

initw deletew

lookupwData structure used by the program

COSC3213 M. Aboelaze

YUFall 2002

Step 2 (dict1.c)/* dict1.c - main, nextin */

#include <stdio.h>#include <ctype.h>

#define MAXWORD 50 /* maximum length of a command or word */

/*------------------------------------------------------------------------* main - insert, delete, or lookup words in a dictionary as specified*------------------------------------------------------------------------*/

intmain(argc, argv)int argc;char *argv[];{

char word[MAXWORD+1]; /* space to hold word from input line */char cmd;int wrdlen; /* length of input word*/

COSC3213 M. Aboelaze

YUFall 2002

Step 2 (dict1.c)while (1) {

wrdlen = nextin(&cmd, word);if (wrdlen < 0)

exit(0);switch (cmd) {case 'I': /* "initialize" */

initw();printf("Dictionary initialized to empty.\n");break;

case 'i': /* "insert" */insertw(word);printf("%s inserted.\n",word);break;

case 'd': /* "delete" */if (deletew(word))

printf("%s deleted.\n",word);else

printf("%s not found.\n",word);break;

COSC3213 M. Aboelaze

YUFall 2002

step 2 (dict1.c)case 'l': /* "lookup" */

if (lookupw(word))printf("%s was found.\n",word);

elseprintf("%s was not found.\n",word);

break;case 'q': /* quit */

printf("program quits.\n");exit(0);

default: /* illegal input */printf("command %c invalid.\n", cmd);break;

}}

}

COSC3213 M. Aboelaze

YUFall 2002

Step 2 (dict1.c)/*------------------------------------------------------------------------

* nextin - read a command and (possibly) a word from the next input line*------------------------------------------------------------------------*/

int nextin(cmd, word)char *cmd, *word;{

int i, ch;

ch = getc(stdin);while (isspace(ch)) ch = getc(stdin);if (ch == EOF) return -1;*cmd = (char) ch; ch = getc(stdin);while (isspace(ch)) ch = getc(stdin);if (ch == EOF) return -1;if (ch == '\n') return 0;i = 0;while (!isspace(ch)) {

if (++i > MAXWORD) {printf("error: word too long.\n"); exit(1);

}*word++ = ch; ch = getc(stdin);

}*word=‘\0’; return i;

}

COSC3213 M. Aboelaze

YUFall 2002

Step 2 (dict2.c)/* dict2.c - initw, insertw, deletew, lookupw */

#define MAXWORD 50 /* maximum length of a command or word */#define DICTSIZ 100 /* maximum number of entries in diction.*/char dict[DICTSIZ][MAXWORD+1];/* storage for a dictionary of words */int nwords = 0; /* number of words in the dictionary */

/*------------------------------------------------------------------------* initw - initialize the dictionary to contain no words at all*------------------------------------------------------------------------*/

intinitw(){

nwords = 0;return 1;

}

COSC3213 M. Aboelaze

YUFall 2002

Step 2 (dict2.c)/*------------------------------------------------------------------------

* insertw - insert a word in the dictionary ------------------------------------------------------------------------ */

int insertw(word)char *word;{

strcpy(dict[nwords], word);nwords++;return nwords;

}/*------------------------------------------------------------------------

* deletew - delete a word from the dictionary*------------------------------------------------------------- */

int deletew(word)char *word;{

int i;

for (i=0 ; i<nwords ; i++)if (strcmp(word, dict[i]) == 0) {

nwords--;strcpy(dict[i], dict[nwords]);return 1;

}return 0;

}

COSC3213 M. Aboelaze

YUFall 2002

Step 2 (dict2.c)/*---------------------------------------------------------------------

* lookupw - look up a word in the dictionary*------------------------------------------------------------------*/

intlookupw(word)char *word;{

int i;

for (i=0 ; i<nwords ; i++)if (strcmp(word, dict[i]) == 0)

return 1;return 0;

}

COSC3213 M. Aboelaze

YUFall 2002

Step 2

• Note that MAXWORD appears in both programs.

• Also, the data structure used to store the words is declared only in dict2.c since it is used only there, dict12.c doesn’t know anything about it

• You may want to check by compiling both programs

cc –c dict1.c cc –c dict2.c

COSC3213 M. Aboelaze

YUFall 2002

Step 3• The rpcgen specification file contains constants, type

definition, and declaration for the client and server program.

• All specifications must be given in the RPC programming language, which is similar to C (string instead of *char).

• The program only define these constants and types shared between client and server.

• The specification file uses upper case names for procedures and programs.

• The names become symbolic references which could be used in a C program.

COSC3213 M. Aboelaze

YUFall 2002

Step 3 (rdict.x)/* rdict.x */

/* RPC declarations for dictionary program */

const MAXWORD = 50; /* maximum length of a command or word */const DICTSIZ = 100; /* number of entries in dictionary */

struct example { /* unused structure declared here to */int exfield1; /* illustrate how rpcgen builds XDR */char exfield2; /* routines to convert structures. */

};/*------------------------------------------------------------------------* RDICTPROG - remote program that provides insert, delete, and lookup*------------------------------------------------------------------------*/

program RDICTPROG { /* name of remote program (not used) */version RDICTVERS { /* declaration of version (see below) */

int INITW(void) = 1;/* first procedure in this program */int INSERTW(string) = 2;/* second procedure in this program */int DELETEW(string) = 3;/* third procedure in this program */int LOOKUPW(string) = 4;/* fourth procedure in this program */

} = 1; /* definition of the program version */} = 0x30090949; /* remote program number (must be */

/* unique) */

COSC3213 M. Aboelaze

YUFall 2002

Step 4

• After the specification has been completed, run the rpcgen program

rpcgen rdixt.x• Rpcgen uses the name of the input

file to generate the output files.• 5 output files are generatedrdict.h rdict_clnt.c rdict_svc.c, rdixt_xdr.c

COSC3213 M. Aboelaze

YUFall 2002

Step 3 (rdict.h)#define RDICTPROG 0x30090949

#define RDICTVERS 1#define INITW 1extern int * initw_1();#define INSERTW 2extern int * insertw_1();#define DELETEW 3extern int * deletew_1();#define LOOKUPW 4extern int * lookupw_1();extern int rdictprog_1_freeresult();

/* the xdr functions */extern bool_t xdr_example();

#endif /*!_RDICT_H_RPCGEN */

/** Please do not edit this file. It was generated using rpcgen.*/#ifndef _RDICT_H_RPCGEN#define _RDICT_H_RPCGEN

#include <rpc/rpc.h>#define MAXWORD 50#define DICTSIZ 100

struct example {int exfield1;char exfield2;

};typedef struct example example;

COSC3213 M. Aboelaze

YUFall 2002

Step 3 (rdict.h explained)

• The declared procedures comprisethe interface version of the server-side stub.

• Procedures names having been generated by taking the declared procedure names, mapping them to lower case, and appending underscore followed by the program number.

• Thus, allowing rpcgen to choose its own naming convention, while allowing the original called procedure not to change

COSC3213 M. Aboelaze

YUFall 2002

The XDR File/*

* Please do not edit this file.* It was generated using rpcgen.*/

#include "rdict.h"

bool_t xdr_example(xdrs, objp)register XDR *xdrs;example *objp;

{

#if defined(_LP64) || defined(_KERNEL)register int *buf;

#elseregister long *buf;

#endif

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

if (!xdr_char(xdrs, &objp->exfield2))return (FALSE);

return (TRUE);}

COSC3213 M. Aboelaze

YUFall 2002

The XDR File• In our example, the only declared type is a

structure with one integer filed and one character filed.

• rdict_xdr.c contains the code needed to convert a structure of type example from the native representation to the external data representation.

• If one of the remote procedures did use the an example structure, rpcgen would generate code in both client and server to call xdr_example to convert the representation.