You are on page 1of 37

Sun RPC Tutorial

Tim Salo

Sai Ram Kuchibhatla


Original (Non-Distributed) Program
RPCdemo.c
#include <stdio.h>

int add(int a, int b) { return a+b; }

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


int i1 = 1;
int i2 = 2;
printf("\n\nThe sum of %i and %i is "
"%i.\n\n\n", i1, i2, add(i1, i2));
}
Original (Non-Distributed) Program
Compile

% gcc -o RPCdemo RPCdemo.c

Execute

% ./RPCdemo

The sum of 1 and 2 is 3.


Skeleton for Distributed Program
RPCdemo.x
Define program Define interface
program RPCDEMO {
version RPCDEMOVERS {

int ADD(int, int) = 1;

} = 1; Define function

} = 0x20004088;

Ensure uniqueness (e.g., last four student ID digits)


Compile Skeleton
%rpcgen -N -a RPCdemo.x

%mv Makefile* Makefile


% ls -l
1118 Feb 6 21:19 Makefile
969 Feb 6 21:19 RPCdemo.h
122 Feb 6 21:03 RPCdemo.x
787 Feb 6 21:19 RPCdemo_client.c
605 Feb 6 21:19 RPCdemo_clnt.c
317 Feb 6 21:19 RPCdemo_server.c
2263 Feb 6 21:19 RPCdemo_svc.c
281 Feb 6 21:19 RPCdemo_xdr.c
Make Skeleton
% make
cc -g -c -o RPCdemo_clnt.o RPCdemo_clnt.c
cc -g -c -o RPCdemo_client.o
RPCdemo_client.c
cc -g -c -o RPCdemo_xdr.o RPCdemo_xdr.c
cc -g -o RPCdemo_client RPCdemo_clnt.o
RPCdemo_client.o RPCdemo_xdr.c -lnsl
cc -g -c -o RPCdemo_svc.o RPCdemo_svc.c
cc -g -c -o RPCdemo_server.o
RPCdemo_server.c
cc -g -o RPCdemo_server RPCdemo_svc.o
RPCdemo_server.o RPCdemo_xdr.o –lnsl
Make Skeleton
% ls -l
122 Feb 6 21:03 RPCdemo.x
21144 Feb 6 21:29 RPCdemo_client*
8056 Feb 6 21:29 RPCdemo_client.o
7464 Feb 6 21:29 RPCdemo_clnt.o
24797 Feb 6 21:29 RPCdemo_server*
7120 Feb 6 21:29 RPCdemo_server.o
11704 Feb 6 21:29 RPCdemo_svc.o
4944 Feb 6 21:29 RPCdemo_xdr.o
RPCdemo.h
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#ifndef _RPCDEMO_H_RPCGEN
#define _RPCDEMO_H_RPCGEN

#include <rpc/rpc.h>

#ifdef __cplusplus
extern "C" {
#endif

struct add_1_argument {
int arg1;
int arg2;
};
typedef struct add_1_argument add_1_argument;
...
RPCdemo_clnt.c
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/

#include <memory.h> /* for memset */


#include "RPCdemo.h"

/* Default timeout can be changed using clnt_control() */


static struct timeval TIMEOUT = { 25, 0 };

int *
add_1(int arg1, int arg2, CLIENT *clnt)
{
add_1_argument arg;
static int clnt_res;
...
RPCdemo_svc.c
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/
#include "RPCdemo.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
...
RPCdemo_xdr.c
/*
* Please do not edit this file.
* It was generated using rpcgen.
*/

#include "RPCdemo.h"

bool_t
xdr_add_1_argument (XDR *xdrs, add_1_argument *objp)
{
if (!xdr_int (xdrs, &objp->arg1))
return FALSE;
if (!xdr_int (xdrs, &objp->arg2))
return FALSE;
return TRUE;
}
RPCdemo_server.c (part 1 of 2)
/*
* This is sample code generated by rpcgen.
* These are only templates and you can use
them
* as a guideline for developing your own
functions.
*/
RPCdemo_server.c (part 2 of 2)
#include "RPCdemo.h"

int * add_1_svc(int arg1, int arg2,


struct svc_req *rqstp) {

static int result;


/*
* insert server code here
*/
return &result;
}
RPCdemo_server.c (modified)
#include "RPCdemo.h"

int * add_1_svc(int arg1, int arg2,


struct svc_req *rqstp) {

static int result;

result = arg1 + arg2;

return &result;
}
RPCdemo_client.c (part 1 of 3)
/*
* This is sample code generated by rpcgen.
* These are only templates and you can use
them
* as a guideline for developing your own
functions.
*/
RPCdemo_client.c (part 2 of 3)
#include "RPCdemo.h"

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


char *host;
...
host = argv[1];
rpcdemo_1 (host);
exit (0);
}
RPCdemo_client.c (part 3 of 3)
void rpcdemo_1(char *host) {
CLIENT *clnt; int *result_1;
int add_1_arg1; int add_1_arg2;
clnt = clnt_create (host, RPCDEMO,
RPCDEMOVERS, "udp");
if (clnt == NULL) {...}
The
result_1 = add_1(add_1_arg1,
real
add_1_arg2, clnt); thing
if (result_1 == (int *) NULL) {...}
clnt_destroy (clnt);
}
RPCdemo_client.c (modified)
void rpcdemo_1(char *host) {
CLIENT *clnt; int *result_1;
int add_1_arg1 = 1;
int add_1_arg2 = 2;
...
result_1 = add_1(add_1_arg1,
add_1_arg2, clnt);
printf("\n\nThe sum of %i and %i is "
"%i.\n\n\n", add_1_arg1,
add_1_arg2, *result_1);
...
}
Run It!
lind24-06% RPCdemo_server

lind24-20% RPCdemo_client lind24-06

The sum of 1 and 2 is 3.


RPCdemo_server.c (Version 2)
int * add_1_svc(int arg1, int arg2,
struct svc_req *rqstp) {

static int result;

result = arg1 + arg2;

printf("add(%i, %i) called.\n",


arg1, arg2);

return &result;
}
Run It! (Version 2)
lind24-06% RPCdemo_server

lind24-20% RPCdemo_client lind24-06

The sum of 1 and 2 is 3.

lind24-06% RPCdemo_server
add(1, 2) called.
Review – All We Did Was...
Create RPCdemo.x

program RPCDEMO {
version RPCDEMOVERS {

int ADD(int, int) = 1;

} = 1;

} = 0x20004088;

Run rpcgen.
Review – All We Did Was...
Modify skeleton server code

int * add_1_svc(int arg1, int arg2,


struct svc_req *rqstp) {

static int result;

result = arg1 + arg2;

return &result;
}
Review – All We Did Was...
Modify skeleton client code.

void rpcdemo_1(char *host) {


int add_1_arg1 = 1;
int add_1_arg2 = 2;
...
result_1 = add_1(add_1_arg1,
add_1_arg2, clnt);
printf("\n\nThe sum of %i and %i is "
"%i.\n\n\n", add_1_arg1,
add_1_arg2, *result_1);
}
Java Remote Method Invocation (RMI)
There are three processes that participate in
supporting remote method invocation.
• The Client
• The Server
• The Object Registry
Remote Interface
package example.hello;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Hello extends Remote {


String sayHello() throws RemoteException;
}
Server (1 of 2)
package example.hello;

import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Server implements Hello {

public Server() {}

public String sayHello() {


return "Hello, world!";
}
Server (2 of 2)
public static void main(String args[]) {

try {
Server obj = new Server();
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);

// Bind the remote object's stub in the registry


Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", stub);

System.err.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
e.printStackTrace();
}
}
}
Client ( 1 of 2)
package example.hello;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {

private Client() {}

public static void main(String[] args) {


String host = (args.length < 1) ? null : args[0];
try {
Registry registry = LocateRegistry.getRegistry(host);
Hello stub = (Hello) registry.lookup("Hello");
Client (2 of 2)
String response = stub.sayHello();
System.out.println("response: " + response);
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
Steps

•Compile all of the Remote interfaces and classes

% javac -d destDir Hello.java Server.java Client.java

•Start Registry

% rmiregistry <port-number> &


Run
Server:
% java -classpath classDir
example.hello.Server &
Output:
Server Ready

Client:
% java -classpath classDir
example.hello.Client
Output:
response: Hello, world!
Concluding Thoughts and Hints
• Why use Sun RPC
– It’s simple
– Its transparent
» You can look at it and see how it works

• But
– It gives the C/Unix error message
» segmentation fault
– It performs C/Unix error checking
» none
» Real programmers don’t make mistakes
Concluding Thoughts and Hints
• So
– Be patient
– Be methodical
– Don’t be too aggressive (maybe)
– Don’t be too tricky
– Develop incrementally
– Save working versions
Concluding Thoughts and Hints
• And
– Use the IT Labs machines
» There are a lot of them
» You can (usually) ssh in
» You won’t fight with firewalls, SELinux

• Careful
– Sun RPC is not reentrant
» Static variables
– Interaction with threads can be messy
Concluding Thoughts and Hints
• Documentation
– man rpc
– man rpcgen
– Sun ONC+ Documentation
– I will update the RPC and RMI resources on
the class Web pages
Concluding Thoughts and Hints

Questions

You might also like