/**********************************************************************************
* Create a TCP/IP client
* TCP client communication uses a TCP client socket object.
* When a TCP socket is created you are assigned a local port number by the O/S.
*
* Usage: TCPclient <hostname> <serverPort>
* 
* @version 2.0
* @author Sam Sultan
**********************************************************************************/
import java.io.*;
import java.net.*;

public class TCPclient
{
    public static void main(String[] args)
    {
        if (args.length != 2) {
            System.out.println("Usage: TCPclient <hostname> <serverPort>");
            System.exit(0);
        }
    
        String readString;                  //string read from sonsole
        String sendString;                  //string to send server
        String recvString = null;           //string received from server

        InetAddress serverIP;               //IP address object for server
        InetAddress clientIP;               //IP address object for client
    
        int serverPort;                     //port number for server
        int clientPort;                     //port number for client

        Socket TCPSocket;                   //TCP socket object

        try
        {
            serverIP   = InetAddress.getByName(args[0]);    //get server hostname -> address
            serverPort = Integer.parseInt(args[1]);         //get server port number        

            TCPSocket = new Socket(serverIP,serverPort);    //establish new client socket

            serverIP   = TCPSocket.getInetAddress();        //get server IP address
            serverPort = TCPSocket.getPort();               //get server port number        
            clientIP   = TCPSocket.getLocalAddress();       //get local IP address
            clientPort = TCPSocket.getLocalPort();          //get local port number 

            System.out.println("Remote Server Name...: " + serverIP.getHostName());
            System.out.println("Remote Server IP Addr: " + serverIP.getHostAddress());
            System.out.println("Remote Server Port...: " + serverPort);
            System.out.println();

            System.out.println("Local  Client Name...: " + clientIP.getHostName());
            System.out.println("Local  Client IP Addr: " + clientIP.getHostAddress());
            System.out.println("Local  Client Port...: " + clientPort);
            System.out.println();

            InputStreamReader keyboard1 = new InputStreamReader(System.in);    //convert to 16 bit
            BufferedReader    keyboard  = new BufferedReader(keyboard1);       //to use readLine()

            InputStream       socketIn1  = TCPSocket.getInputStream();          //ref to socket input 
            InputStreamReader socketIn2  = new InputStreamReader(socketIn1);    //convert to 16 bit
            BufferedReader    socketIn   = new BufferedReader(socketIn2);       //to use readLine()

            OutputStream       socketOut1 = TCPSocket.getOutputStream();        //ref to socket output 
            OutputStreamWriter socketOut2 = new OutputStreamWriter(socketOut1); //convert to 16 bit
            PrintWriter        socketOut  = new PrintWriter(socketOut2);        //buffered and can use println()

            /*------------------ read data from keyboard -------------------*/

            while(true)
            {       
                System.out.print("Enter something: ");          //prompt        
                readString = keyboard.readLine();              //read from keyboard
                readString = readString.trim();                 //trim white space

                if (readString.length() == 0)                   //empty line?
                    break;

                /*------------------ send data ---------------------------*/
    
                sendString = readString;

                System.out.println("Sending........: " + sendString ); 
                System.out.println();

                socketOut.println(sendString);          //send data thru the socket     
                socketOut.flush();                      //flush buffer

                System.out.println("Waiting for server... "+ serverIP +":"+ serverPort);
                System.out.println();

                /*------------------ receive data -------------------------*/
    
                System.out.println("Received.......: ");

//              recvString = socketIn.readLine();         //receive data from the socket, single line only
//              System.out.println(recvString);                                 

                while(true)                               //use for multiple lines 
                {                    
                    recvString = socketIn.readLine();
                    if (recvString.length() == 0) break;  //empty line?
//                  if (recvString == null) break;        //empty line?
                    System.out.println(recvString);                                 
                }                               
                recvString = socketIn.readLine();         //flush whatever is in socket. 
                System.out.println();
            }

            System.out.println("Closing connection to "+ serverIP +":"+ serverPort);

            keyboard.close();
            socketIn.close();
            socketOut.close();
            TCPSocket.close();
            System.exit(0);
        }

        catch(UnknownHostException e)
        {
            System.out.println("Unknown host: " + args[0]);
            System.exit(-1);
        }

        catch(IOException e)
        {   
            System.out.println("I/O error: " + e.toString());
            System.exit(-1);
        }
    }
}