TCP Programming
Chat Server

Modified

Video of Chat Server 5

This exercise is designed to illustrate and provide practice for network programming tasks common to many server applications. The format of the exercise is:

  1. begin with a very simple server application
  2. identify a problem or reasonable improvement
  3. propose and design a solution
  4. implement the solution
  5. test the implementation.

Chat Server - Chat servers connect two or more clients so that the input of one client is output to all other clients. Attempt number zero of a chat server that reads a line of text from the keyboard and prints to the screen is below. No networking is done so the server isn't really a server but does illustrate some of the general structure of a chat server.

  1. Copy and paste the following program into an editor.
  2. Save as:
  3. Compile and execute in a Command Prompt window by:
  4. Type a few lines into the window.
// chatserver0.java Use: java -cp . chatserver0



 import java.io.*;



 class chatserver0 {

     public static void main(String args[]) throws Exception {

         new server0().run();                       // run server

     }

 }



 class server0 {

    public void run() {

        String from;

        BufferedReader in=null;                       // input and output

        PrintStream    out=null;



        try {                    

            in = new BufferedReader(new InputStreamReader( System.in )); 

            out = new PrintStream( System.out );



            System.out.println("Connected");   // Read line 

            while( (from=in.readLine()) != null && !from.equals("")) {

                 System.out.println( from );

                 out.print(from + "\r\n");      // Print line 

            }

       }

       catch(IOException e) {}                     // catch IO errors

       System.out.println("Disconnected");

    }

 }

Java Programming Points
 

  • new server0( ) - Constructs a server0 object.
  • new server0( ).run( ); - Calls the run method on the server0 object
  • try - Defines the start of an exception handling block. Any errors occuring within the block will terminate the block and restart execution at the next catch that matches the exception, in this case only IOException errors are caught.
  • in = new BufferedReader(new InputStreamReader( System.in)); - Constructs a object that can read the input from the keyboard. System.in is predefined keyboard input.
  • out = new PrintStream(System.out); - Basically same as above except for output to the screen.
  • from=in.readLine( ) - Reads a line of text from the input object in. The text must be terminated by "\r\n" which is not input. If the input were:
    • Hello World\r\n

    from="Hello World"

  • System.out.println( from ); - Outputs from to the screen.
  • out.print(from + "\r\n") - Prints the value of  from with "\r\n" concatenated to the out object.
  • catch(IOException e) {}- Catch point for any IOException exceptions occuring within the try block above. The object e could be printed or other actions taken with the { } block.

Exercise 0 - Obviously chat version 0 needs networking. Try to identify points within the program where:

  1. the server waits for the client connection,
  2. the input of the connection is constructed,
  3. the output of the connection is constructed,
  4. the client input is read,
  5. the client output is printed.

Exercise 1 - Chat server version 1 implements network communication with a TCP client. Test the chat server by:

  1. Copy and paste the following program into an editor.
  2. Save as:
  3. Compile and execute in a Command Prompt window by:
  4. Run a client telnet session to connect with the chat server in another Command Prompt window by:
  5. Type a few lines into the telnet window.
  6. Determine by testing:
    1. whether more than one client telnet sessions can be handled by the chat server at the same time,
    2. whether it continues after the client connection is closed,
    3. other server weaknesses.
// chatserver1.java Use: java -cp . chatserver1



import java.net.*;

import java.io.*;



class chatserver1 {

    public static void main(String args[]) throws Exception {

        ServerSocket conn = new ServerSocket( 888 );

        new server1( conn.accept() ).run();          // Wait for connection/run server

    }

}



class server1 {

   Socket s;

 

   server1(Socket s) {                             // Construct new server1

       this.s = s;                                         // Socket accepted a connection

   }



   public void run() {

       String from;

       BufferedReader in=null;                       // Socket input and output

       PrintStream    out=null;



       try {                    

           in = new BufferedReader(new InputStreamReader(s.getInputStream())); 

           out = new PrintStream(s.getOutputStream());



           System.out.println("Connected");   // Read line from client

           while( (from=in.readLine()) != null && !from.equals("")) {

                System.out.println( from );

                out.print(from + "\r\n");           // Print line to client     

           }

           s.close();                                     // Close connection

      }

      catch(IOException e) {}                     // catch IO errors

      System.out.println("Disconnected");

   }

}


Comparison of Non-networked and Networked Program

// chatserver0.java Use: java -cp . chatserver0



 import java.io.*;



 class chatserver0 {

  public static void main(String args[])  throws Exception {

      new server0().run();                       

  }

 }







 class server0 {













    public void run() {

        String from;

        BufferedReader in=null;                    

        PrintStream    out=null;



        try {                    

            in = new BufferedReader(

                     new InputStreamReader(System.in)); 

            out = new PrintStream(System.out);



            System.out.println("Connected");         

            while( (from=in.readLine()) != null && 

                    !from.equals("")) {

                 System.out.println( from );

                 out.print(from + "\r\n");            

            }

       }

       catch(IOException e) {}                       

       System.out.println("Disconnected");

    }

 }
// chatserver1.java Use: java -cp . chatserver1



import java.net.*;

import java.io.*;



class chatserver1 {

  public static void main(String args[])  throws Exception {

    ServerSocket conn = new ServerSocket( 888 );

    new server1(conn.accept()).run();          

  }

}



class server1 {

   Socket s;

 

   server1(Socket s) {                             

       this.s = s;                                 

   }



   public void run() {

     String from;

     BufferedReader in=null;                     

     PrintStream    out=null;



     try {                    

       in = new BufferedReader(

                new InputStreamReader(s.getInputStream())); 

       out = new PrintStream(s.getOutputStream());



       System.out.println("Connected");         

       while( (from=in.readLine()) != null && 

               !from.equals("")) {

          System.out.println( from );

          out.print(from + "\r\n");                

       }

       s.close();                              

      }

      catch(IOException e) {}                      

      System.out.println("Disconnected");

   }

}

Java Programming Points
 

  • ServerSocket conn = new ServerSocket( 888 ); - Constructs a ServerSocket object named conn that listens on port 888.
  • conn.accept() - Waits for a connection on ServerSocket object conn. Returns a Socket when the connection is completed.
  • new server1(conn.accept( )) - Constructs a new server1 object using the socket connected to the client.
  • new server1(conn.accept( )).run( ) - Executes the server1 method named run.
  • try - Defines the start of an exception handling block. Any errors occuring within the block will terminate the block and restart execution at the next catch that matches the exception, in this case only IOException errors are caught.
  • in = new BufferedReader(new InputStreamReader( s.getInputStream( ))); - Constructs a object that can read the input from the client. The client is connected on socket s so that s.getInputStream( ) returns the socket input.
  • out = new PrintStream(s.getOutputStream()); - Basically same as above except for output.
  • from=in.readLine( ) - Reads a line of text from the input object in. The text must be terminated by "\r\n" which is not input. If the input of the connection were:
    • Hello World\r\n

    from="Hello World"
     

  • System.out.println( from ); - Outputs from to the screen.
  • out.print(from + "\r\n") - Prints the value of from with "\r\n" concatenated to the socket connection output.
  • catch(IOException e) {}- Catch point for any IOException exceptions occuring within the try block above. The object e could be printed or other actions taken with the { } block.

Exercise 2 - One weakness is that the server terminates when the client connection is closed. The server should wait for another connection rather than terminating.

  1. Propose a solution,
  2. implement the solution, the instructor will help.
  3. Name the new program file and class:
  4. Name the server class:
  5. Test.
  6. Side-by-side comparison of chatserver1 and chatserver2.

Exercise 3 - A serious weakness for the chat server is that only a single client can be connected at a time. The server should allow multiple simultaneous connections.

  1. Propose a solution,
  2. implement the solution, the instructor will help.
  3. Name the new program file and class:
  4. Name the server class:
  5. Test.
  6. Side-by-side comparison of chatserver2 and chatserver3.

Exercise 4 - The server still has a serious weakness in that the multiple clients can't chat to each other!

  1. Propose a solution  keeping in mind that each client has an independent connection to the server,
  2. implement the solution, the instructor will help.
  3. Name the new program file and class:
  4. Name the server class:
  5. Test.
  6. Side-by-side comparison of chatserver3 and chatserver4.

Exercise 5 - The server should usually behave as expected but has a potential hazard. Each client connection is running in a separate thread on the server. When multiple clients attempt to connect at the same time, updates to the vector holding the client connection is in a race condition. One thread could begin accessing the vector, be suspended, and another thread undo or corrupt the vector. 

  1. Identify the hazard,
  2. propose a solution,
  3. implement the solution, the instructor will help.
  4. Name the new program file and class:
  5. Name the server class:
  6. Test.
  7. Side-by-side comparison of chatserver4 and chatserver5.