import java.io.*; import java.net.*; /** ThreadedEchoServer.java This program implements a multithreaded server that listens to port given by two command line arguments. The server echoes back all client input on port given by first argument and monitored the number of echo clients on port given by seconf argument. */ class ClientCounter { public ClientCounter(){ counter=0; } public synchronized void increment(){ counter++; } public synchronized long getValue(){ return counter; } private long counter; } public class ThreadedEchoServerMonitored { public static void main(String[] args ){ try{ ClientCounter i = new ClientCounter(); new Monitor(i, Integer.parseInt(args[1])).start(); ServerSocket s = new ServerSocket(Integer.parseInt(args[0])); for (;;){ Socket incoming = s.accept( ); i.increment(); System.out.println("Spawning " + i.getValue()); Thread t = new ThreadedEchoHandler(incoming, i.getValue()); t.start(); } } catch (Exception e) { e.printStackTrace(); } } } class Monitor extends Thread { public Monitor( ClientCounter i, int port) { this.i=i; this.port=port; } public void run (){ try { ServerSocket ms = new ServerSocket (port); while(true) { Socket mc = ms.accept(); PrintWriter out = new PrintWriter(mc.getOutputStream(), true); out.println(" "+i.getValue()); mc.close(); } } catch (Exception e) { e.printStackTrace(); } } private ClientCounter i; private int port; } /** This class handles one client input. */ class ThreadedEchoHandler extends Thread { public ThreadedEchoHandler(Socket i, long n) { incoming = i; numOrder = n; } public void run() { try { BufferedReader in = new BufferedReader (new InputStreamReader(incoming.getInputStream())); PrintWriter out = new PrintWriter (incoming.getOutputStream(), true /* autoFlush */); out.println( "Hello! Enter BYE to exit." ); boolean done = false; while (!done) { String str = in.readLine(); if (str == null) done = true; else { out.println("Echo = "+str); if (str.trim().equals("BYE")) done = true; } } incoming.close(); if(numOrder==1) System.exit(0); } catch (Exception e) { e.printStackTrace(); } } private Socket incoming; private long numOrder; }