Académique Documents
Professionnel Documents
Culture Documents
Invocation
Search
Modified: 12/01/2006 06:16:29
Overview
Time Client/Server
o
Exercise 1 - Time Client/Server
Distributed Processing
o
Exercise 2 - Sort Client/Server
Multiple SortServerImpl
o
Exercise 3 - Multiple Sort Client
Threading
o
Exercise 4 - Threaded Multiple Sort Client
site
po
Time Client/Server
We will implement a simple Time service client/server using Java RMI.
Clients obtain the current time by invoking a method getTime( ) on the
remote time server. There are three Java files necessary to implement a
client/server relation using RMI:
1. Interface - TimeServerInf.java - Interface definition of all server
methods that can be called by the remote client. The server
implementation must define String getTime( )method.
2. Server - TimeServerImpl.java - Implements the methods that are
defined in the interface (i.e. String getTime( ) ).
3. Client - TimeClient.java - Client calls to remote methods on the
server, (i.e. getTime( ) ).
// TimeServerInf.java interface definition
import java.rmi.*;
public interface TimeServerInf extends Remote {
public String getTime() throws RemoteException;
}
// TimeServerImpl.java
import java.rmi.*;
import java.rmi.server.*;
public class TimeServerImpl extends UnicastRemoteObject implements
TimeServerInf {
public TimeServerImpl() throws RemoteException { super(); }
// implementation for TimeServerInf interface method, return the
current date/time as String
public String getTime() {
return new java.util.Date().toString();
}
public static void main( String args[] ) throws Exception {
System.err.println( "Initializing server: please wait." );
// create server object and bind TimeServerImpl object to the
rmiregistry on default port 1099
);
}
}
// TimeClient.java
import java.rmi.*;
public class TimeClient {
public static void main( String args[] ) throws Exception {
// lookup TimeServerInf remote object in rmiregistry on port 1099
of local host
TimeServerInf ts = (TimeServerInf) Naming.lookup(
"//localhost/Time" );
// get time from server
System.out.println(ts.getTime());
}
TimeClient Output
The time is: Tue Jun 19 11:30:36 EDT 2001
RMI software components - The RMI software components include
the infrastructure to suppport a programming model where apparent
communication is directly between the client and server as illustrated at
left below.
Apparent
Client/Server
Communication
}
}
//
TimeClient.java
import java.rmi.*;
public class TimeClient {
public static void main( String args[] ) throws Exception {
String host = "localhost";
if (args.length > 0) host = args[0];
// lookup TimeServerInf remote object in rmiregistry
TimeServerInf ts = (TimeServerInf) Naming.lookup( "//" +
host + "/Time" );
// get time from server
System.out.println(ts.getTime());
}
}
Output:
ray-laptop/127.0.0.1 Tue Jun 19 11:02:59 EDT 2001
set
classpath=%classpath%;.;C:\JDK1.2.2\lib\class
es.zip
javac *.java
rmic -v1.2 TimeServerImpl
start rmiregistry
start java TimeServerImpl
java TimeClient
components
Define classpath to
Java components
Compile all Java
programs.
Generate a Java 2
TimeServerImpl_Stub.c
lass used by client to
invoke RMI server
methods.
Start the RMI registry
used to bind server
objects to host and port
number (normally port
1099).
Start the server and
bind to host and port
number.
Execute client invoking
getTime method on
server.
Distributed Processing
RMI is a general remote computing model that can support virtually any
client/server application. The TimeClient/TimeServerImpl was an
example of RMI as a server, where the server provided time a s a
service to the client. As an example of distributed processing, sorting on
a server will be examined where multiple servers each sort a part of an
array and the client merges the parts into a whole sorted array. First a
simpler example of a single server sorting a client array.
The key software elements are the same as before:
1. Interface - SortServerInf.java - Interface definition of all server
methods that can be called by the remote client. The server
implementation must define method:
int[] sort(int data[])
2. Server - SortServerImpl.java - Implements the methods that are
defined in the interface (i.e. int[] sort(int data[]) ).
3. Client - SortClient.java - Client calls to remote methods on the
server, (i.e. int[] sort(int data[]) ).
Sort Client/Server
// SortServerInf.java interface definition
import java.rmi.*;
public interface SortServerInf extends Remote {
public int[] sort( int data[] ) throws RemoteException;
}
// SortServerImpl.java
import java.rmi.*;
import java.rmi.server.*;
public class SortServerImpl extends UnicastRemoteObject implements
SortServerInf {
public SortServerImpl() throws RemoteException { super(); }
// implementation for SortServerInf interface method
public int[] sort( int data[] ) {
int n = data.length;
int temp;
for (int pass = 0; pass < n-1; pass++)
for (int pair=0; pair < n-pass-1; pair++)
if( data[pair] < data[pair+1]) {
temp = data[pair];
data[pair] = data[pair+1];
data[pair+1] = temp;
}
return data;
}
public static void main( String args[] ) throws Exception {
System.err.println( "Initializing server: please wait." );
String number = "";
if (args.length > 0) number = args[0];
// create server object and bind SortServerImpl object to the
rmiregistry
Naming.rebind( "//localhost/Sort" + number, new
SortServerImpl() );
System.out.println("Unsorted Sorted");
for (int i=0; i<unsorted.length; i++)
System.out.println(unsorted[i] + "
" + sorted[i]);
}
Output:
Unsorted Sorted
93
95
81
93
95
81
74
74
2. SortServerImpl.java
3. SortClient.java.
2. Copy and paste the commands below left. Due to startup race
conditions, the SortClient may start before the SortServerImpl is
fully running, you will need to enter the last line again by hand if
the SortClient fails.
3. Find out a class mate's machine IP or name that is running
the SortServerImpl and have it. To sort from lf111-b0.ius.edu by:
o java SortClient lf111-b0.ius.edu
4. What changes are needed to run multiple servers:
0. Changes to the SortServerInf.java?
1. Changes to the SortServerImpl.java?
2. Changes to the SortClient.java?
3. Changes to the command below?
Running the Sort Client/Server
path=C:\JDK1.2.2\BIN;%path%
Define path to Java
set
components
classpath=%classpath%;.;C:\JDK1.2.2\lib\class Define classpath to
es.zip
Java components
javac *.java
Compile all Java
rmic -v1.2 SortServerImpl
programs.
start rmiregistry
Generate a Java 2
start java SortServerImpl
SortServerImpl_Stub.cl
java SortClient
ass used by client to
invoke RMI server
methods.
Start the RMI registry
used to bind server
objects to host and
port number (normally
port 1099).
Start the server and
bind to host and port
number.
Execute client invoking
sort method on server.
Multiple SortServerImpl
A more realistic distributed processing example would be to have
multiple SortServerImpl each sorting an array that is returned to the
client and merged to produce a fully sorted array.
The apparent object transfer between the client and the two server
is:
//
import java.rmi.*;
public class MultiSortClient {
public static void main( String args[] ) throws Exception {
int
int
int
int
System.out.println("Sorted");
for (int i=0; i<sorted.length; i++)
System.out.println(sorted[i]);
}
private int[] merge(int s1[], int s2[]) {
int merged[] = new int[s1.length+s2.length];
int i1=0, i2=0;
}
Output:
Sorted
95
95
93
93
81
81
74
74
0.
1.
2.
3.
Changes
Changes
Changes
Changes
to
to
to
to
the
the
the
the
SortServerInf.java?
SortServerImpl.java?
MultiSortClient.java?
command below?
Threading
The multiple sort client above has one serious weakness, although the
sorting is distributed amoung several sort servers no advantage is
gained in reduced overall time. This can be understood by an
examination of the client and recalling that remote method invocations
behave as a regular method invocation, the caller is blocked until the
method returns. In the following the second invocation is not made until
the first is completed:
sorted1 = ss1.sort(unsorted1);
// Wait till completed
sorted2 = ss2.sort(unsorted2);
// Wait till completed
The time the client and server SS1 and SS2 execute can be illustrated
as:
where each
executes sequentially. Ideally both sorts would occur simultaneously,
This can be achieved by making each server sort invocation in a
seperate thread on the client and waiting for each server to finished
before merging the sorted arrays. The following implements a threaded
client that is in other aspects the same as the previous example. The
key changes are:
1. an additional class SortThread
1. that runs a thread for calling a sort server,
2. can be checked for sort completion,
3. returns the sorted array.
2. the client
1. creates and runs one thread for each server,
2. while a server is sorting waits,
3. when all servers are finished sorting, retrieves the sorted
array.
With the use of threads the sort servers can be started and monitored
for completion. The execution of the client and sort servers SS1 and SS2
is illustrated at right. Each can execute in parallel so that the time to
complete is, in theory at least, reduced. Because of networking and RMI
overhead, reduced execution time
may not be a fact.
// TMultiSortClient.java
import java.rmi.*;
class SortThread extends Thread {
int unsorted[], sorted[];
SortServerInf ss;
String name;
boolean sorting;
public SortThread(SortServerInf ss,
int unsorted[], String name) {
this.unsorted = unsorted;
this.ss = ss;
this.name = name;
sorting = true;
}
public int[] getSorted() {
return sorted;
}
public void run() {
System.out.println("Started
thread " + name);
try {
sorted =
ss.sort(unsorted);
} catch(Exception e) {}
System.out.println("Finished
thread " + name);
sorting = false;
}
public boolean sorting() {
return sorting;
}
}
public class TMultiSortClient {
public static void main( String args[]
) throws Exception {
int unsorted1[] = {93, 81, 95,
74};
74};
SortServerInf ss2 =
(SortServerInf) Naming.lookup( "//" +
host2 + "/Sort2" );
// Start sort threads
thread1 = new
SortThread(ss1, unsorted1,
"Sort1");
thread2 = new
SortThread(ss2, unsorted2,
"Sort2");
thread1.start();
thread2.start();
// Wait while either thread is
sorting
while(thread1.sorting() ||
thread2.sorting())
System.out.println("Sorting");;
sorted = new
TMultiSortClient().merge(thread1.getS
orted(), thread2.getSorted());
System.out.println("Sorted");
for (int i=0; i<sorted.length;
i++)
System.out.println(sorted[i
]);
}
private int[] merge(int s1[], int
s2[]) {
int merged[] = new
int[s1.length+s2.length];
int i1=0, i2=0;
for (int i=0; i<merged.length;
i++)
if (i1 == s1.length)
merged[i] = s2[i2++];
else if (i2 == s2.length)
merged[i] = s1[i1++];