import java.io.Serializable; import java.rmi.*; import java.rmi.server.UnicastRemoteObject; import Utilities.*; /* * To get this example to work on Windows 95, I had to start up dial-up * networking, call my ISP, and start PPP. This eliminated the access * exception thrown contacting rmiregistry starting the ComputeServer. */ public interface Compute extends Remote { public abstract Work compute(Work w) throws RemoteException; } class Work extends MyObject implements Serializable { private double[] a = null, b = null, c = null; private final int N = 5; public Work() { this("Work"); } public Work(String fromWhom) { super("Work from " + fromWhom); a = new double[N]; b = new double[N]; c = new double[N]; for (int i = 0; i < N; i++) { a[i] = random(-N, N); b[i] = random(-N, N); } } public void doWork() { nap(1+(int)random(1000*N)); // simulate some computation time for (int i = 0; i < N; i++) c[i] = a[i] + b[i]; } public String toString() { String value = "\n" + getName(); value += "\na="; for (int i = 0; i < N; i++) value += " " + a[i]; value += "\nb="; for (int i = 0; i < N; i++) value += " " + b[i]; value += "\nc="; for (int i = 0; i < N; i++) value += " " + c[i]; return value; } } class ComputeServer extends UnicastRemoteObject implements Compute { private static String serverName = "ComputeServer"; private String name = null; private static boolean debug = false; public ComputeServer(String name) throws RemoteException { super(); this.name = name; } public Work compute(Work w) throws RemoteException { if (debug) System.out.println(name + " got work request:" + w); w.doWork(); if (debug) System.out.println(name + " sending reply:" + w); return w; } public static void main(String args[]) { // parse command line options, if any, to override defaults GetOpt go = new GetOpt(args, "UdM:"); go.optErr = true; String usage = "Usage: -d -M serverMachine"; String serverMachine = "cheshire"; int ch = -1; while ((ch = go.getopt()) != go.optEOF) { if ((char)ch == 'U') { System.out.println(usage); System.exit(0); } else if ((char)ch == 'd') debug = true; else if ((char)ch == 'M') serverMachine = go.optArgGet(); else { System.err.println(usage); System.exit(1); } } // install the appropriate security manager System.setSecurityManager(new RMISecurityManager()); // contact rmiregistry if (debug) { try { String[] list = Naming.list("rmi://" + serverMachine); System.out.println("list.length=" + list.length); for (int i = 0; i < list.length; i++) System.out.println("list[" + i + "]=" + list[i]); } catch (Exception e) { System.err.println(serverName + " exception " + e); System.exit(1); } } // register this server try { ComputeServer server = new ComputeServer(serverName); Naming.bind("rmi://" + serverMachine + "/" + serverName, server); } catch (Exception e) { System.err.println(serverName + " exception " + e); System.exit(1); } System.out.println("server " + serverName + " has been created on " + serverMachine + "\n and bound in the registry to the name " + serverName); } } class Client extends MyObject implements Runnable { private int id = -1; private Compute server = null; private int napTime = 0; private Client(int id, Compute server, int napTime) { super("Client " + id); this.id = id; this.server = server; this.napTime = napTime; new Thread(this).start(); } public void run() { Work w = null; while (true) { nap(1 + (int) random(napTime)); w = new Work(getName()); System.out.println("age=" + age() + ", " + getName() + " sending to server work:" + w); try { w = server.compute(w); } catch (Exception e) { System.err.println("Client exception " + e); System.exit(1); } System.out.println("age=" + age() + ", " + getName() + " received from server reply:" + w); } } public static void main(String[] args) { // parse command line options, if any, to override defaults GetOpt go = new GetOpt(args, "UM:N:c:n:R:"); go.optErr = true; String usage = "Usage: -M serverMachine -N serverName" + " -c numClients -n napTime -R runTime"; String serverMachine = "cheshire"; String serverName = "ComputeServer"; int numClients = 3; int napTime = 4; // both in int runTime = 20; // seconds int ch = -1; while ((ch = go.getopt()) != go.optEOF) { if ((char)ch == 'U') { System.out.println(usage); System.exit(0); } else if ((char)ch == 'M') serverMachine = go.optArgGet(); else if ((char)ch == 'N') serverName = go.optArgGet(); else if ((char)ch == 'c') numClients = go.processArg(go.optArgGet(), numClients); else if ((char)ch == 'n') napTime = go.processArg(go.optArgGet(), napTime); else if ((char)ch == 'R') runTime = go.processArg(go.optArgGet(), runTime); else { System.err.println(usage); System.exit(1); } } System.out.println("Client: serverMachine=" + serverMachine + ", serverName=" + serverName + ", numClients=" + numClients + "\n napTime=" + napTime + ", runTime=" + runTime); Compute server = null; try { server = (Compute) Naming.lookup("rmi://" + serverMachine + "/" + serverName); } catch (Exception e) { System.err.println("Client exception " + e); System.exit(1); } for (int i = 0; i < numClients; i++) new Client(i, server, 1000*napTime); // let the Clients run for a while nap(runTime*1000); System.out.println("age()=" + age() + ", time to stop the threads and exit"); System.exit(0); } } /* ............... Example compile and run(s) % javac Compute.java % rmic ComputeServer % rmiregistry 7777 & % sleep 5; java ComputeServer -M jubjub:7777 & server ComputeServer has been created on jubjub:7777 and bound in the registry to the name ComputeServer % sleep 5; rsh cheshire "java Client -M jubjub:7777 -R10" Client: serverMachine=jubjub:7777, serverName=ComputeServer, numClients=3 napTime=4, runTime=10 age=2017, Client 0 sending to server work: Work from Client 0 a= -4.08339 2.16857 4.40555 -0.748032 -4.94281 b= 3.84741 1.73436 3.72347 -2.84654 3.26483 c= 0 0 0 0 0 age=4602, Client 1 sending to server work: Work from Client 1 a= -3.74569 4.42188 1.02479 2.70581 -0.496568 b= -3.19404 -2.76756 -1.57525 4.34111 -3.47821 c= 0 0 0 0 0 age=5262, Client 2 sending to server work: Work from Client 2 a= -1.67754 -3.87383 -1.19787 -4.46458 4.26563 b= -1.15187 3.56791 -3.88024 0.670651 2.12482 c= 0 0 0 0 0 age=6871, Client 1 received from server reply: Work from Client 1 a= -3.74569 4.42188 1.02479 2.70581 -0.496568 b= -3.19404 -2.76756 -1.57525 4.34111 -3.47821 c= -6.93972 1.65432 -0.550468 7.04692 -3.97478 age=7291, Client 0 received from server reply: Work from Client 0 a= -4.08339 2.16857 4.40555 -0.748032 -4.94281 b= 3.84741 1.73436 3.72347 -2.84654 3.26483 c= -0.23598 3.90294 8.12902 -3.59457 -1.67798 age=7504, Client 2 received from server reply: Work from Client 2 a= -1.67754 -3.87383 -1.19787 -4.46458 4.26563 b= -1.15187 3.56791 -3.88024 0.670651 2.12482 c= -2.82941 -0.30592 -5.07811 -3.79393 6.39045 age=8292, Client 0 sending to server work: Work from Client 0 a= 0.720275 4.73046 -0.677494 -3.91055 3.09876 b= 1.34022 2.81506 3.91125 4.32273 -0.521754 c= 0 0 0 0 0 age=8811, Client 1 sending to server work: Work from Client 1 a= 2.92618 0.166923 -3.43393 -4.5423 -4.83467 b= -3.63099 2.5937 1.27995 -0.00706403 2.29606 c= 0 0 0 0 0 age=10180, Client 0 received from server reply: Work from Client 0 a= 0.720275 4.73046 -0.677494 -3.91055 3.09876 b= 1.34022 2.81506 3.91125 4.32273 -0.521754 c= 2.06049 7.54552 3.23376 0.412184 2.57701 age=10312, Client 2 sending to server work: Work from Client 2 a= -3.46919 -0.71782 -3.55013 4.81676 2.3632 b= -3.1488 4.15626 1.32766 -1.47453 0.955188 c= 0 0 0 0 0 age()=11460, time to stop the threads and exit ... end of example run(s) */