Multi-Threaded Server

The discussion for each program will include two parts: first, the basic thread logic and, second, the complete code.

Skeleton

public class Server_Threaded extends Frame  {

  public boolean action (Event event, Object arg) {

    if (event.target == listenButton )  {
      listen = new ListenServer ( this );
      listen.start ();  
    }  // end listenButton 

  }  // end action

}  // end Server_Threaded 

// ********************  ListenServer Class *******************

class ListenServer extends Thread  {

ListenServer ( Frame s)  {
  // figure out port
      listenSocket = new ServerSocket ( port );
}  // end constructor 

public void run  ()  {
    while ( again )  {
      Socket connection = listenSocket.accept();
      HandleServer handleServer = new HandleServer ( connection, source );
    }  // end while
}  // end run

}  // end ListenServer 

// ********************  HandleServer Class *******************

class HandleServer extends Thread  {

HandleServer ( Socket client, Frame s)  {
    input = client.getInputStream ();
    output = client.getOutputStream ();
  this.start ();
}  // end constructor

public void run  ()  {
    while ( again )  {
        stringIn = getMsg ( input );
        if ( ! (stringIn.equals( "$")) ) {  // valid message
        }  // end if
        else  {  // end of session
          again = false;
            client.close ();
         }  // end else
    }  // end while
}  // end run

}  // end HandleServer 

Complete Program

import java.lang.Thread;
import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.*;

public class Server_Threaded extends Frame  {

//*****  Single-thread server, accepts multiple messages
//            expected to be run on capefear.cs.unc.edu:8888


public static final String DEFAULT_HOST = "gamma.cs.unc.edu";
public static final int DEFAULT_PORT = 8888;
String host;
ListenServer listen;

MyFrame outerBox;
TextField hostDisplay, portDisplay;
TextArea logDisplay, msgDisplay;
Panel topPanel;
Panel middlePanel;
Panel buttonPanel;
Button listenButton, quitButton;


// **************

  public Server_Threaded ()  {
    super ( "Server_Threaded " );
  }  // end Server_Threaded constructor

// **************

  public static void main ( String [ ] args )  {
    Server_Threaded server = new Server_Threaded ();
    server.buildUI ();
  }  // end main

// **************

  public boolean action (Event event, Object arg) {

    if (event.target == listenButton )  {
      listen = new ListenServer ( this );
      listen.start ();  
      return true;
    }  // end listenButton 

    if (event.target == quitButton )  {
      hide ();
      dispose ();
      System.exit ( 0 );
      return true;
    }  // end quitButton 

    return false;  // action not handled here

  }  // end action

// **************

  public boolean handleEvent ( Event event )  {

    if ( event.id == Event.WINDOW_ICONIFY )  {
      hide ();
      dispose ();
      System.exit ( 0 );
    }  // end if

    return super.handleEvent ( event );

  }  // end handleEvent 

// **************

// **************

  public void buildUI ()  {

  try {
    InetAddress here = InetAddress.getLocalHost ();
    host = here.toString();
  }
  catch (UnknownHostException e) { ;}
  hostDisplay = new TextField ( host, 30 );
  portDisplay = new TextField ( Integer.toString ( DEFAULT_PORT ), 4 );
  topPanel = new Panel ();
  topPanel.setLayout ( new BorderLayout () );
  topPanel.add ( "North", hostDisplay );
  topPanel.add ( "South", portDisplay );

  logDisplay = new TextArea ( 40, 10 );
  msgDisplay = new TextArea ( 40, 10 );
  middlePanel = new Panel ();
  middlePanel.setLayout ( new GridLayout ( 2, 1 ) );
  middlePanel.add ( logDisplay );
  middlePanel.add ( msgDisplay );

  listenButton = new Button ( "Listen" );
  quitButton = new Button ( "Quit" );
  buttonPanel = new Panel ( );
  buttonPanel.add ( listenButton );
  buttonPanel.add ( quitButton );

  outerBox = new MyFrame ( this, "Server_Threaded" );
  outerBox.add ( "North", topPanel );
  outerBox.add ( "Center", middlePanel );
  outerBox.add ( "South", buttonPanel );

  outerBox.resize ( 350, 400 );
  outerBox.show ();

  }  // end buildUI 

}  // end Server_Threaded 



// ********************  ListenServer Class *******************

class ListenServer extends Thread  {
  Server_Threaded source;
  ServerSocket listenSocket;
  int port;
  Socket connection;
  HandleServer handle;
  boolean again = true;

// **************

ListenServer ( Frame s)  {
    super ();
    source = (Server_Threaded ) s;

    if ( ! ( source.portDisplay.getText () ).equals ( "" ) ) port = Integer.parseInt ( source.portDisplay.getText () );
    else port = source.DEFAULT_PORT;

    try  {
      source.logDisplay.setText ( "Server started:  listening on port " + port + "\n" );
      listenSocket = new ServerSocket ( port );
    }  catch ( IOException except )  {
          except.printStackTrace ();
    }  // end catch

}  // end constructor 

// **************

public void run  ()  {

  try  {
    while ( again )  {
      Socket connection = listenSocket.accept();
      HandleServer handleServer = new HandleServer ( connection, source );
    }  // end while
  }  catch ( IOException except )  {
        except.printStackTrace ();
  }  // end catch

}  // end run

}  // end ListenServer 


// ********************  HandleServer Class *******************

class HandleServer extends Thread  {
  Server_Threaded source;
  Socket client;
  OutputStream output;
  InputStream input;
  String stringIn, stringOut;

// **************

HandleServer ( Socket connection, Frame s)  {
  super ();
  client = connection;
  source = (Server_Threaded) s;

  try  {
    input = client.getInputStream ();
    output = client.getOutputStream ();
  }  catch ( IOException except )  {
     except.printStackTrace ();
     try { client.close(); } catch ( IOException e) {;}
     return;
  }  // end catch
  this.start ();

}  // end constructor

// **************

public void run  ()  {
  String stringIn, stringOut;
  boolean again = true;

  source.logDisplay.appendText ( "Adding Client\n" );

    while ( again )  {

        stringIn = getMsg ( input );
        if ( ! (stringIn.equals( "$")) ) {  // valid message
          source.msgDisplay.setText ( stringIn);
          source.logDisplay.appendText ( "Message, below, received\n" );
          putMsg ( output, source.msgDisplay.getText () );
          source.logDisplay.appendText ( "Message, below, sent to client \n" );
          source.logDisplay.appendText ( "Message length = " + ( source.msgDisplay.getText () ).length () + "\n" );
        }  // end if

        else  {  // end of session
          again = false;
          source.logDisplay.appendText ( "Closing socket\n" );
           try {
            client.close ();
           }  // end try
             catch ( IOException except)  {
             except.printStackTrace ();
           }  // end catch
         }  // end else

    }  // end while

}  // end run

// **************

  public String getMsg ( InputStream input )  {
    char[] charArray = new char [ 1024 ];
    char c;
    int i = 0;
        try {
            while ( ( (c = (char) input.read () ) != '#' ) && (i < 1024) ) {
             charArray [ i ] =  c ;
             i++;
           }  // end while
        }  catch ( IOException except )  {
          except.printStackTrace ();
        }  // end catch
         String string = new String ( String.valueOf ( charArray, 0, i ) );
          return string;
  }  // end getMsg

  public void putMsg ( OutputStream output, String string )  {
    try {
      for ( int i = 0; i < string.length(); i++ ) {
        output.write ( (int) string.charAt ( i ) );
      }  // end for
      output.write ( (int)'#' );  // end of message mark
    }  catch ( IOException except )  {
       except.printStackTrace ();
    }  // end catch
  }  // end putMsg


}  // end HandleServer 


// ********************  MyFrame Class *******************


class MyFrame extends Frame  {
  Frame source;

  MyFrame ( Frame a )  {
    super ( );
    source = a;
  }  // end constructor

  MyFrame ( Frame a, String title )  {
    super ( title );
    source = a;
  }  // end constructor

  public boolean action ( Event event, Object object )  {
    if ( source.action ( event, object ) ) return true;
    else return false;
  }  // end action

  public boolean handleEvent ( Event event )  {
    if ( source.handleEvent ( event ) ) return true;
    else return super.handleEvent ( event );
  }  // end handleEvent

}  // end MyFrame