//Java packages
import java.net.*;
import java.io.*;

public class socketServer{
	
	//Main method start
 	public static void main(String args[]){
 		
 		//Varible declaration statements
  		int port;
  		ServerSocket server_socket;
  		Socket child_socket;
  		Echo_Child my_child;  
  		
  		if (args.length != 1) 
    		System.out.println("Usage: java echoserver server_port");   
    		 
  		else{
			try{ 
				//Read the argument
				//And convert port from type string to type int
       			port = Integer.parseInt(args[0]);
       			
       			//Step 1
       			//Create a ServerSocket and to assign a port number
       			server_socket = new ServerSocket(port);
       			
       			System.out.println("Server is waiting for incoming connections on port " 
       								+ server_socket.getLocalPort());

       				//Step 2
       				//Wait for a connection
          			child_socket = server_socket.accept(); 
          			
          			System.out.println("Accepted a new connection from client [" 
          								+ child_socket.getInetAddress() +
                             			":" + child_socket.getPort() + "]");
          			
          			//Jump to the Echo_Child class to process input and output streams
          			my_child = new Echo_Child(child_socket);
          			my_child.start();
      		}
     		catch (Exception e){e.printStackTrace();}
    	}
 	}
}

class Echo_Child extends Thread{
	
 	Socket child_socket;
 	BufferedReader input;
 	PrintWriter output;
 	String message;

 	public Echo_Child(Socket s) throws Exception{

  		child_socket = s;
  		
  		//Step 3
  		//Get input and output streams
  		input = new BufferedReader(new InputStreamReader(child_socket.getInputStream())); 
  		output = new PrintWriter(child_socket.getOutputStream(),true);
 	}
 	
 	//Create a thread
 	public void run(){
 		
  		try {
  			
  			//Step 4
  			//Process connection
    		while(true){
    			
    			//Get input streams
       			message = input.readLine(); 
       			
       			if (message==null) 
         			break;
         		
       			System.out.println("Recieved: " + message);  
       			 
       			//Output the streams from the input streams 
       			output.println(message);
      		}
      		
    		System.out.println("Client [" + child_socket.getInetAddress() +
                       ":" + child_socket.getPort() +
                       "] has closed the connection.");
            
            //Step 5
            //Close connection
    		child_socket.close();
   		} 
  		catch(Exception e){e.printStackTrace();}
 	}
}