package cs522.elind.rmi; import java.io.*; import java.net.*; import java.rmi.*; import java.rmi.registry.*; import java.rmi.server.*; import cs522.elind.base.*; import cs522.elind.io.*; public class RMIChat extends UnicastRemoteObject implements ChatRemote { protected boolean statsDisplayed = false; protected boolean keepRunning = true; protected BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); protected String host = "localhost"; protected int localPort = 1100; protected int remotePort = 1101; protected String myName = ""; protected String buddyName = ""; protected ChatRemote buddy = null; protected MonitorSocket serverMs = null; protected MonitorSocket clientMs = null; protected MonitorInputStream serverInStream = null; protected MonitorOutputStream serverOutStream = null; protected MonitorInputStream clientInStream = null; protected MonitorOutputStream clientOutStream = null; protected MonitorSocketFactory msf = null; protected MonitorServerSocketFactory mssf = null; PrintWriter fw = null; long br = 0; long bw = 0; public RMIChat() throws RemoteException { super(); new Thread(new KeyboardReader()).start(); } public RMIChat(int port) throws RemoteException { super(port); new Thread(new KeyboardReader()).start(); } public RMIChat(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException { super(0, csf, ssf); msf = (MonitorSocketFactory)csf; mssf = (MonitorServerSocketFactory)ssf; try { host = InetAddress.getLocalHost().getHostAddress(); File outputFile = new File("RMIChat"+port+".txt"); fw = new PrintWriter(new FileWriter(outputFile)); } catch(Exception e) { e.printStackTrace(); } localPort = port; new Thread(new KeyboardReader()).start(); } public void connect(String buddyHost, int buddyPort) throws RemoteException { registerRemote(buddyHost, buddyPort); } public void register() { try { Registry registry = LocateRegistry.createRegistry(localPort); registry.rebind("RMIChat", this); } catch(RemoteException e) { System.err.println("A RemoteException occurred during RMIChat setup"); e.printStackTrace(); System.exit(1); } } public void registerRemote(String hostName, int port) { try { Registry remoteRegistry = LocateRegistry.getRegistry(hostName, port); buddy = (ChatRemote)remoteRegistry.lookup("RMIChat"); } catch(NotBoundException e) { System.err.println("Could not bind to remote registry"); e.printStackTrace(); System.exit(1); } catch(RemoteException e) { System.err.println("A RemoteException occurred during Remote setup"); e.printStackTrace(); System.exit(1); } establishMonitors(); } public void establishMonitors() { try { MonitorServerSocket mss = mssf.getLastSocket(); serverMs = mss.getLastMonitorSocket(); if(serverMs != null) { serverInStream = (MonitorInputStream)serverMs.getInputStream(); serverOutStream = (MonitorOutputStream)serverMs.getOutputStream(); br = serverInStream.bytesRead(); bw = serverOutStream.bytesWritten(); fw.println("establishMonitors() bytesRead = "+(serverInStream.bytesRead() - br)); fw.println("establishMonitors() bytesWritten = "+(serverOutStream.bytesWritten() - bw)); } MonitorSocket ms = msf.getLastSocket(); if(ms != null) { clientInStream = (MonitorInputStream)clientMs.getInputStream(); clientOutStream = (MonitorOutputStream)clientMs.getOutputStream(); br = clientInStream.bytesRead(); bw = clientOutStream.bytesWritten(); fw.println("establishMonitors() bytesRead = "+(clientInStream.bytesRead() - br)); fw.println("establishMonitors() bytesWritten = "+(clientOutStream.bytesWritten() - bw)); } } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { RMIChat rc = null; if(args.length == 1 || args.length==3) { try { MonitorSocketFactory temp = new MonitorSocketFactory(); rc = new RMIChat(Integer.parseInt(args[0]), temp, new MonitorServerSocketFactory()); rc.msf = temp; rc.register(); } catch(Exception e) { e.printStackTrace(); } } else { System.err.println("usage: java RMIChat localPort [buddy_host_name buddy_port]"); System.exit(1); } if(args.length == 3) { rc.registerRemote(args[1], Integer.parseInt(args[2])); try { rc.buddy.connect(rc.host, rc.localPort); rc.establishMonitors(); } catch(RemoteException e) { e.printStackTrace(); } } } protected synchronized void displayStats() { if(!statsDisplayed) { fw.println("Bytes received = "+serverInStream.bytesRead()); fw.println("Bytes written = "+serverOutStream.bytesWritten()); statsDisplayed = false; } } protected void send(Message msg) { try { buddy.receive(msg); fw.println("send("+msg+") bytesRead = "+(serverInStream.bytesRead() - br)); fw.println("send("+msg+") bytesWritten = "+(serverOutStream.bytesWritten() - bw)); } catch(Exception e) { e.printStackTrace(); } br = serverInStream.bytesRead(); bw = serverOutStream.bytesWritten(); } public void receive(Message msg) throws RemoteException { System.out.println(msg.getTimeStamp()+" - "+msg.getText()); fw.println("receive("+msg+") bytesRead = "+(serverInStream.bytesRead() - br)); fw.println("receive("+msg+") bytesWritten = "+(serverOutStream.bytesWritten() - bw)); } class KeyboardReader implements Runnable { public void run() { String line = ""; try { while(keepRunning) { line = stdIn.readLine(); if(line == null) { break; } br = serverInStream.bytesRead(); bw = serverOutStream.bytesWritten(); send(new Message(line)); } } catch(Exception e) { keepRunning = false; } displayStats(); fw.close(); System.exit(0); } } }