import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.ServerSocket;

class Test {
    static final int port = 4444;
    static final int maxque = 2;

    public static void main(String A[]) {
        try {
            ServerSocket SERV= new ServerSocket(port, maxque);
            System.out.println("Test server started at port "+port);

            for (int i=0; i<5; i++) {
                HandleClient C=new HandleClient(SERV, i);
                Thread T=new Thread(C);
                T.start();
            }
        } catch (Exception e) {
            System.out.println("Fatal Ops! "+e);
        }
        System.out.println("The server has started with all worker threads running!");
    }
}

class HandleClient implements Runnable {
    ServerSocket SE;
    int co;

    HandleClient(ServerSocket server, int clinum) {
        SE=server;
        co=clinum;
    }

    public void run() {
        while(!SE.isClosed()) {
            try {
                Socket SO = SE.accept();
                System.out.println(co+"> A new client connected from "+SO.getInetAddress());
    
                BufferedReader SR = new BufferedReader(new InputStreamReader(SO.getInputStream()));
                PrintWriter    SW = new PrintWriter (SO.getOutputStream());
    
                SW.println("You are serving by the client thread number "+co+".");
                SW.println("I am listening to you.");
                SW.flush();
                System.out.println(co+"> listening...");
                while (true) {
                    String line=SR.readLine();
                    if (line==null) break;
                    System.out.println(co+"> "+line);
                    if (line.equals("!STOP")) {
                        SW.println(co+"> Terminating server on your request. No new connections will be allowed.");
                        SW.flush();
                        System.out.println(co+"> Terminating server on your request. No new connections will be allowed.");
                        SO.close();
                        SE.close();
                    }
                }
                SO.close();
                System.out.println(co+"> The client closed connection.");
            } catch (Exception e) {
                System.out.println(co+"> Ops! "+e);
            }
        }
    }
}