0% found this document useful (0 votes)
142 views

Sun RPC Tutorial: Sai Ram Kuchibhatla

This document provides an overview of using Sun RPC (Remote Procedure Call) to create a distributed program. It demonstrates how to define a remote interface using RPCGEN, compile the client and server stubs, modify the skeleton code to implement the remote function, and run the distributed program. It also compares RPC to Java RMI (Remote Method Invocation), showing how RMI uses interfaces, stubs, and a registry to allow remote calls between a client and server.

Uploaded by

Vishnu Reddy
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
142 views

Sun RPC Tutorial: Sai Ram Kuchibhatla

This document provides an overview of using Sun RPC (Remote Procedure Call) to create a distributed program. It demonstrates how to define a remote interface using RPCGEN, compile the client and server stubs, modify the skeleton code to implement the remote function, and run the distributed program. It also compares RPC to Java RMI (Remote Method Invocation), showing how RMI uses interfaces, stubs, and a registry to allow remote calls between a client and server.

Uploaded by

Vishnu Reddy
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 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