/**************************************************************************************************
* Create a UDP/IP client
* UDP communication uses IP packets and a UDP socket to communicate.
* a UDP packet needs to contain the IP address & port of the remote machine, as well as the data.  
* a UDP socket needs to be created to perform the communication.
* as a client, when a UDP socket is created you are assigned a port number by the O/S.
*
* Usage: UDPclient <hostname> <serverPort>
* 
* @version 1.0
* @author Sam Sultan
***************************************************************************************************/
import java.io.*;
import java.net.*;

public class UDPclient
{
    public static void main(String[] args)
    {
        if (args.length != 2) {
            System.out.println("Usage: UDPclient <hostname> <serverPort>");
            System.exit(0);
        }
    
        String readString;                  //string read from console keyboard
        String sendString;                  //string to convert send array
        String recvString;                  //string to convert receive array

        byte[] sendArray = new byte[256];   //array to send data to client 
        byte[] recvArray = new byte[256];   //array to receive data from client

		int recvLength;

        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

        DatagramPacket sendPacket;          //UDP packet object to send
        DatagramPacket recvPacket;          //UDP packet object to receive

        DatagramSocket UDPsocket;           //UDP socket object

        try
        {
            serverIP   = InetAddress.getByName(args[0]);    //get server hostname -> address
            serverPort = Integer.parseInt(args[1]);         //get server 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();

            //create 2 IP packets - empty packet
            recvPacket = new DatagramPacket(recvArray, recvArray.length);
            sendPacket = new DatagramPacket(sendArray, sendArray.length, serverIP, serverPort);

            UDPsocket = new DatagramSocket();               //establish new client socket
                                                            //OS will assign the next port

            clientIP   = InetAddress.getLocalHost();        //get local hostname -> address
            clientPort = UDPsocket.getLocalPort();          //get local port from socket 

            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()

            while(true)
            {
            /*------------------ reading from console keyboard ----------------------------*/

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

                if (readString.length() == 0)                   //empty line?
                {           
                    keyboard.close();
                    UDPsocket.close();
                    System.exit(0);
                }

                /*------------------ sending data --------------------------------------*/
    
                sendString = readString;
                sendArray  = readString.getBytes();         //convert string to byte array

                sendPacket.setData(sendArray);				//write data in send packet

//              System.out.println("to server name: " + sendPacket.getAddress().getHostName());
//              System.out.println("at IP address.: " + sendPacket.getAddress().getHostAddress());
//              System.out.println("at port number: " + sendPacket.getPort());

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

                UDPsocket.send(sendPacket);                             //send the packet       

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

                /*------------------ receiving data --------------------------------------*/
    
                UDPsocket.receive(recvPacket);          //receive the packet

//              System.out.println("from server name: " + recvPacket.getAddress().getHostName());
//              System.out.println("at IP address...: " + recvPacket.getAddress().getHostAddress());
//              System.out.println("at port number..: " + recvPacket.getPort());

                recvArray  = recvPacket.getData();          //extract data from packet
				recvLength = recvPacket.getLength();		//number of bytes received

                recvString = new String(recvArray,0,recvLength);  //convert to string;
                recvString = recvString.trim();                   //trim white space

                System.out.println("Received.......: " + recvString ); 
                System.out.println();
            }
        }
        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);
        }
    }
}