// Client that reads and displays information sent from a Server.
import java.io.*;
import java.net.*;

public class client{
        private ObjectOutputStream output;
        private ObjectInputStream input;
        private String chatServer;
        private Socket connection;

        public client( String host ){
                chatServer = host;
        }

        private void runClient(){
                try{
                        //Step 1: Create a Socket to make connection
                        connection = new Socket( chatServer, 12345 );

                        //Step 2: Get the input and output streams
                        output = new ObjectOutputStream( connection.getOutputStream() );
                        output.flush();
                        input = new ObjectInputStream( connection.getInputStream() );

                        //Step 3: Process connection
                        processConnection();
                }
                catch( EOFException eofException ){ System.err.println( "Client terminated connection" ); }
                catch( IOException ioException ){ ioException.printStackTrace(); }
                finally{ closeConnection(); }
        }

        //process connection with server
        private void processConnection() throws IOException{
                String message = "connected (client)";
                sendData( message );
                BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
                do{//process messages sent from server
                        try{
                                message = (String) input.readObject();
                                System.out.print( message + "\n" );
                                message = br.readLine();
                                sendData( message );
                        }
                        catch( ClassNotFoundException cNFE ){ System.out.print( "\nUnknown object type received" ); }

                }while( !message.equals( "TERMINATE" ) );
        }

        //close streams and socket
        private void closeConnection(){
                try {
                        output.close();
                        input.close();
                        connection.close();
                }
                catch( IOException ioException ){ ioException.printStackTrace(); }
        }

        //send message to server
        private void sendData( String message ){
                try{
                        output.writeObject( message );
                        output.flush();
                }
                catch( IOException ioException ){ System.out.print( "\nError writing object" ); }
        }

        public static void main( String args[] ){
                client application;
                application = new client( args[ 0 ] );
                application.runClient();
        }
}

// Set up a Server that will receive a connection from a client, send
// a string to the client, and close the connection.
import java.io.*;
import java.net.*;

public class server{
        private ObjectOutputStream output;
        private ObjectInputStream input;
        private ServerSocket srvr;
        private Socket connection;
        private int counter = 1;

        public server(){

        }

        // set up and run server
        public void runServer(){
                // set up server to receive connections; process connections
                try{
                        //Step 1: Create a ServerSocket.
                        srvr = new ServerSocket( 12345, 100 );
                        while( true ){
                                try{
                                        //Step 2: Wait for a connection.
                                        connection = srvr.accept();
                                        getStreams(); //Step 3: Get input & output streams.
                                        processConnection(); //Step 4: Process connection.
                                }
                                catch( EOFException eofException ){ System.err.println( "Server terminated connection" ); }
                                finally{ closeConnection(); ++counter; }
                        }
                }
                catch( IOException ioException ){ ioException.printStackTrace(); }
        }

        //get streams to send and receive data
        private void getStreams() throws IOException{//set up output stream for objects
                output = new ObjectOutputStream( connection.getOutputStream() );
                output.flush(); //flush output buffer to send header information
                input = new ObjectInputStream( connection.getInputStream() );
        }

        //process connection with client
        private void processConnection() throws IOException{
                String message = "";
                sendData( "connected (server)\n" );
                do{ //process messages sent from client
                        try{
                        message = (String) input.readObject();
                                System.out.print( message + "\n" );
                                sendData( "" );
                        }
                        catch( ClassNotFoundException cNFE ){ System.out.print( "Unknown object type received\n" ); }

                }while( !message.equals( "CLIENT>>> TERMINATE" ) );

        }

        // close streams and socket
        private void closeConnection(){
                System.out.print( "\nTerminating connection\n" );
                try{
                        output.close();
                        input.close();
                        connection.close();
                }
                catch( IOException ioException ){ ioException.printStackTrace(); }
        }

        //send message to client
        private void sendData( String message ){//send object to client
                try{
                        output.writeObject( message );
                        output.flush();
                }
                catch ( IOException ioException ){ System.out.print( "\nError writing object" ); }
        }

        public static void main( String args[] ){
                server application = new server();
                application.runServer();
        }

}