Beruflich Dokumente
Kultur Dokumente
Tim Salo
Execute
% ./RPCdemo
The sum of 1 and 2 is 3.
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
21144 Feb
8056 Feb
7464 Feb
24797 Feb
7120 Feb
11704 Feb
4944 Feb
6
6
6
6
6
6
6
6
21:03
21:29
21:29
21:29
21:29
21:29
21:29
21:29
RPCdemo.x
RPCdemo_client*
RPCdemo_client.o
RPCdemo_clnt.o
RPCdemo_server*
RPCdemo_server.o
RPCdemo_svc.o
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
#include
#include
#include
#include
#include
#include
#include
"RPCdemo.h"
<stdio.h>
<stdlib.h>
<rpc/pmap_clnt.h>
<string.h>
<memory.h>
<sys/socket.h>
<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;
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
RPCdemo_server.c (Version 2)
int * add_1_svc(int arg1, int arg2,
struct svc_req *rqstp) {
static int
result;
lind24-06% RPCdemo_server
add(1, 2) called.
result;
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);
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!
But
It gives the C/Unix error message
segmentation fault
It performs C/Unix error checking
none
Real programmers dont make mistakes
Careful
Sun RPC is not reentrant
Static variables
Interaction with threads can be messy
Questions