Multithread TicTacToe Server Problem

I'm having some problems with finishing up a tic tac toe server and it's driving me crazy. I'm hoping someone can give me some hints or help out with this. All of the code is written for the server which allows 2 clients to connect, but the code for determining if the game is won needs to be finished up.
I've got the method for determining if the game is over done, that part is easy, and I'm able to send a message to the client who wins when they place the winning marker and end the game for them, but currently the next player gets to place one more marker before being signaled that the game is over. I worked on this forever and I think I'm just missing something simple that I hope someone can help me with. Here's the code:
Line 180 in TicTacToeServer.java is where I test for the win
Line 304 in TicTacToeServer.java is where the clients exit the main while loop after determining that the game is won and I send a message letting them know that the game is won
Server Code:
TicTacToeServerTest.java
// Tests the TicTacToeServer.
import javax.swing.JFrame;
public class TicTacToeServerTest
   public static void main( String args[] )
      TicTacToeServer application = new TicTacToeServer();
      application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
      application.execute();
   } // end main
} // end class TicTacToeServerTest
TicTacToeServer.java
// This class maintains a game of Tic-Tac-Toe for two clients.
import javax.swing.JOptionPane;
import java.awt.BorderLayout;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.util.Formatter;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class TicTacToeServer extends JFrame
   private String[] board = new String[ 9 ]; // tic-tac-toe board
   private JTextArea outputArea; // for outputting moves
   private Player[] players; // array of Players
   private ServerSocket server; // server socket to connect with clients
   private int currentPlayer; // keeps track of player with current move
   private final static int PLAYER_X = 0; // constant for first player
   private final static int PLAYER_O = 1; // constant for second player
   private final static String[] MARKS = { "X", "O" }; // array of marks
   private ExecutorService runGame; // will run players
   private Lock gameLock; // to lock game for synchronization
   private Condition otherPlayerConnected; // to wait for other player
   private Condition otherPlayerTurn; // to wait for other player's turn
   private int winner = 2;
   // set up tic-tac-toe server and GUI that displays messages
   public TicTacToeServer()
      super( "Tic-Tac-Toe Server" ); // set title of window
      // create ExecutorService with a thread for each player
      runGame = Executors.newFixedThreadPool( 2 );
      gameLock = new ReentrantLock(); // create lock for game
      // condition variable for both players being connected
      otherPlayerConnected = gameLock.newCondition();
      // condition variable for the other player's turn
      otherPlayerTurn = gameLock.newCondition();
      for ( int i = 0; i < 9; i++ )
         board[ i ] = new String( "" ); // create tic-tac-toe board
      players = new Player[ 2 ]; // create array of players
      currentPlayer = PLAYER_X; // set current player to first player
      try
         server = new ServerSocket( 12345, 2 ); // set up ServerSocket
      } // end try
      catch ( IOException ioException )
         ioException.printStackTrace();
         System.exit( 1 );
      } // end catch
      outputArea = new JTextArea(); // create JTextArea for output
      add( outputArea, BorderLayout.CENTER );
      outputArea.setText( "Server awaiting connections\n" );
      setSize( 300, 300 ); // set size of window
      setVisible( true ); // show window
   } // end TicTacToeServer constructor
   // wait for two connections so game can be played
   public void execute()
      // wait for each client to connect
      for ( int i = 0; i < players.length; i++ )
         try // wait for connection, create Player, start runnable
            players[ i ] = new Player( server.accept(), i );
            runGame.execute( players[ i ] ); // execute player runnable
         } // end try
         catch ( IOException ioException )
            ioException.printStackTrace();
            System.exit( 1 );
         } // end catch
      } // end for
      gameLock.lock(); // lock game to signal player X's thread
      try
         players[ PLAYER_X ].setSuspended( false ); // resume player X
         otherPlayerConnected.signal(); // wake up player X's thread
      } // end try
      finally
         gameLock.unlock(); // unlock game after signalling player X
      } // end finally
   } // end method execute
   // display message in outputArea
   private void displayMessage( final String messageToDisplay )
      // display message from event-dispatch thread of execution
      SwingUtilities.invokeLater(
         new Runnable()
            public void run() // updates outputArea
               outputArea.append( messageToDisplay ); // add message
            } // end  method run
         } // end inner class
      ); // end call to SwingUtilities.invokeLater
   } // end method displayMessage
   // determine if move is valid
   public boolean validateAndMove( int location, int player )
      // while not current player, must wait for turn
      while ( player != currentPlayer )
         gameLock.lock(); // lock game to wait for other player to go
         try
            otherPlayerTurn.await(); // wait for player's turn
         } // end try
         catch ( InterruptedException exception )
            exception.printStackTrace();
         } // end catch
         finally
            gameLock.unlock(); // unlock game after waiting
         } // end finally
      } // end while
      // if location not occupied, make move
      if ( !isOccupied( location ) )
         board[ location ] = MARKS[ currentPlayer ]; // set move on board
         currentPlayer = ( currentPlayer + 1 ) % 2; // change player
         // let new current player know that move occurred
         players[ currentPlayer ].otherPlayerMoved( location );
         gameLock.lock(); // lock game to signal other player to go
         try
            otherPlayerTurn.signal(); // signal other player to continue
         } // end try
         finally
            gameLock.unlock(); // unlock game after signaling
         } // end finally
         return true; // notify player that move was valid
      } // end if
      else // move was not valid
         return false; // notify player that move was invalid
   } // end method validateAndMove
   // determine whether location is occupied
   public boolean isOccupied( int location )
      if ( board[ location ].equals( MARKS[ PLAYER_X ] ) ||
         board [ location ].equals( MARKS[ PLAYER_O ] ) )
         return true; // location is occupied
      else
         return false; // location is not occupied
   } // end method isOccupied
   // place code in this method to determine whether game over
   public boolean isGameOver()
      for (int x = 0; x < 2; x++)
           if ((board[0].equals(MARKS[x]) && board[1].equals(MARKS[x]) && board[2].equals(MARKS[x])) ||
            (board[3].equals(MARKS[x]) && board[4].equals(MARKS[x]) && board[5].equals(MARKS[x])) ||
            (board[6].equals(MARKS[x]) && board[7].equals(MARKS[x]) && board[8].equals(MARKS[x])) ||
            (board[0].equals(MARKS[x]) && board[4].equals(MARKS[x]) && board[8].equals(MARKS[x])) ||
            (board[6].equals(MARKS[x]) && board[4].equals(MARKS[x]) && board[2].equals(MARKS[x])) ||
            (board[0].equals(MARKS[x]) && board[3].equals(MARKS[x]) && board[6].equals(MARKS[x])) ||
            (board[1].equals(MARKS[x]) && board[4].equals(MARKS[x]) && board[7].equals(MARKS[x])) ||
            (board[2].equals(MARKS[x]) && board[5].equals(MARKS[x]) && board[8].equals(MARKS[x]))
            winner = x;
             return true;
      return false; // this is left as an exercise
   } // end method isGameOver
   // private inner class Player manages each Player as a runnable
   private class Player implements Runnable
      private Socket connection; // connection to client
      private Scanner input; // input from client
      private Formatter output; // output to client
      private int playerNumber; // tracks which player this is
      private String mark; // mark for this player
      private boolean suspended = true; // whether thread is suspended
      // set up Player thread
      public Player( Socket socket, int number )
         playerNumber = number; // store this player's number
         mark = MARKS[ playerNumber ]; // specify player's mark
         connection = socket; // store socket for client
         try // obtain streams from Socket
            input = new Scanner( connection.getInputStream() );
            output = new Formatter( connection.getOutputStream() );
         } // end try
         catch ( IOException ioException )
            ioException.printStackTrace();
            System.exit( 1 );
         } // end catch
      } // end Player constructor
      // send message that other player moved
      public void otherPlayerMoved( int location )
               output.format( "Opponent moved\n" );
              output.format( "%d\n", location ); // send location of move
              output.flush(); // flush output
      } // end method otherPlayerMoved
      // control thread's execution
      public void run()
         // send client its mark (X or O), process messages from client
         try
            displayMessage( "Player " + mark + " connected\n" );
            output.format( "%s\n", mark ); // send player's mark
            output.flush(); // flush output
            // if player X, wait for another player to arrive
            if ( playerNumber == PLAYER_X )
               output.format( "%s\n%s", "Player X connected",
                  "Waiting for another player\n" );
               output.flush(); // flush output
               gameLock.lock(); // lock game to  wait for second player
               try
                  while( suspended )
                     otherPlayerConnected.await(); // wait for player O
                  } // end while
               } // end try
               catch ( InterruptedException exception )
                  exception.printStackTrace();
               } // end catch
               finally
                  gameLock.unlock(); // unlock game after second player
               } // end finally
               // send message that other player connected
               output.format( "Other player connected. Your move.\n" );
               output.flush(); // flush output
            } // end if
            else
               output.format( "Player O connected, please wait\n" );
               output.flush(); // flush output
            } // end else
            // while game not over
            while ( !isGameOver() )
               int location = 0; // initialize move location
               if ( input.hasNext() )
                  location = input.nextInt(); // get move location
               // check for valid move
               if ( validateAndMove( location, playerNumber ) )
                  displayMessage( "\nlocation: " + location );
                  output.format( "Valid move.\n" ); // notify client
                  output.flush(); // flush output
               } // end if
               else // move was invalid
                  output.format( "Invalid move, try again\n" );
                  output.flush(); // flush output
               } // end else
            } // end while
            output.format( "Game Over.\n" ); // notify client
            if (winner == 0)
                 output.format("Winner is X\n");
            if (winner == 1)
                 output.format("Winner is O\n");
            output.flush(); // flush output
            gameLock.unlock();
         } // end try
         finally
            try
               connection.close(); // close connection to client
            } // end try
            catch ( IOException ioException )
               ioException.printStackTrace();
               System.exit( 1 );
            } // end catch
         } // end finally
      } // end method run
      // set whether or not thread is suspended
      public void setSuspended( boolean status )
         suspended = status; // set value of suspended
      } // end method setSuspended
   } // end class Player
} // end class TicTacToeServer
Client Code:
TicTacToeClientTest.java
// Tests the TicTacToeClient class.
import javax.swing.JFrame;
public class TicTacToeClientTest
   public static void main( String args[] )
      TicTacToeClient application; // declare client application
      // if no command line args
      if ( args.length == 0 )
         application = new TicTacToeClient( "127.0.0.1" ); // localhost
      else
         application = new TicTacToeClient( args[ 0 ] ); // use args
      application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
   } // end main
} // end class TicTacToeClientTest
TicTacToeClient.java
// Client that let a user play Tic-Tac-Toe with another across a network.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.Socket;
import java.net.InetAddress;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import java.util.Formatter;
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
public class TicTacToeClient extends JFrame implements Runnable
   private JTextField idField; // textfield to display player's mark
   private JTextArea displayArea; // JTextArea to display output
   private JPanel boardPanel; // panel for tic-tac-toe board
   private JPanel panel2; // panel to hold board
   private Square board[][]; // tic-tac-toe board
   private Square currentSquare; // current square
   private Socket connection; // connection to server
   private Scanner input; // input from server
   private Formatter output; // output to server
   private String ticTacToeHost; // host name for server
   private String myMark; // this client's mark
   private boolean myTurn; // determines which client's turn it is
   private final String X_MARK = "X"; // mark for first client
   private final String O_MARK = "O"; // mark for second client
   // set up user-interface and board
   public TicTacToeClient( String host )
      ticTacToeHost = host; // set name of server
      displayArea = new JTextArea( 4, 30 ); // set up JTextArea
      displayArea.setEditable( false );
      add( new JScrollPane( displayArea ), BorderLayout.SOUTH );
      boardPanel = new JPanel(); // set up panel for squares in board
      boardPanel.setLayout( new GridLayout( 3, 3, 0, 0 ) );
      board = new Square[ 3 ][ 3 ]; // create board
      // loop over the rows in the board
      for ( int row = 0; row < board.length; row++ )
         // loop over the columns in the board
         for ( int column = 0; column < board[ row ].length; column++ )
            // create square
            board[ row ][ column ] = new Square( " ", row * 3 + column );
            boardPanel.add( board[ row ][ column ] ); // add square
         } // end inner for
      } // end outer for
      idField = new JTextField(); // set up textfield
      idField.setEditable( false );
      add( idField, BorderLayout.NORTH );
      panel2 = new JPanel(); // set up panel to contain boardPanel
      panel2.add( boardPanel, BorderLayout.CENTER ); // add board panel
      add( panel2, BorderLayout.CENTER ); // add container panel
      setSize( 300, 225 ); // set size of window
      setVisible( true ); // show window
      startClient();
   } // end TicTacToeClient constructor
   // start the client thread
   public void startClient()
      try // connect to server, get streams and start outputThread
         // make connection to server
         connection = new Socket(
            InetAddress.getByName( ticTacToeHost ), 12345 );
         // get streams for input and output
         input = new Scanner( connection.getInputStream() );
         output = new Formatter( connection.getOutputStream() );
      } // end try
      catch ( IOException ioException )
         ioException.printStackTrace();
      } // end catch
      // create and start worker thread for this client
      ExecutorService worker = Executors.newFixedThreadPool( 1 );
      worker.execute( this ); // execute client
   } // end method startClient
   // control thread that allows continuous update of displayArea
   public void run()
      myMark = input.nextLine(); // get player's mark (X or O)
      SwingUtilities.invokeLater(
         new Runnable()
            public void run()
               // display player's mark
               idField.setText( "You are player \"" + myMark + "\"" );
            } // end method run
         } // end anonymous inner class
      ); // end call to SwingUtilities.invokeLater
      myTurn = ( myMark.equals( X_MARK ) ); // determine if client's turn
      // receive messages sent to client and output them
      while ( true )
         if ( input.hasNextLine() )
            processMessage( input.nextLine() );
      } // end while
   } // end method run
   // process messages received by client
   private void processMessage( String message )
      // valid move occurred
      if ( message.equals( "Valid move." ) )
         displayMessage( "Valid move, please wait.\n" );
         setMark( currentSquare, myMark ); // set mark in square
      } // end if
      else if ( message.equals( "Invalid move, try again" ) )
         displayMessage( message + "\n" ); // display invalid move
         myTurn = true; // still this client's turn
      } // end else if
      else if ( message.equals( "Opponent moved" ) )
         int location = input.nextInt(); // get move location
         input.nextLine(); // skip newline after int location
         int row = location / 3; // calculate row
         int column = location % 3; // calculate column
         setMark(  board[ row ][ column ],
            ( myMark.equals( X_MARK ) ? O_MARK : X_MARK ) ); // mark move
         displayMessage( "Opponent moved. Your turn.\n" );
         myTurn = true; // now this client's turn
      } // end else if
      else
         displayMessage( message + "\n" ); // display the message
   } // end method processMessage
   // manipulate outputArea in event-dispatch thread
   private void displayMessage( final String messageToDisplay )
      SwingUtilities.invokeLater(
         new Runnable()
            public void run()
               displayArea.append( messageToDisplay ); // updates output
            } // end method run
         }  // end inner class
      ); // end call to SwingUtilities.invokeLater
   } // end method displayMessage
   // utility method to set mark on board in event-dispatch thread
   private void setMark( final Square squareToMark, final String mark )
      SwingUtilities.invokeLater(
         new Runnable()
            public void run()
               squareToMark.setMark( mark ); // set mark in square
            } // end method run
         } // end anonymous inner class
      ); // end call to SwingUtilities.invokeLater
   } // end method setMark
   // send message to server indicating clicked square
   public void sendClickedSquare( int location )
      // if it is my turn
      if ( myTurn )
         output.format( "%d\n", location ); // send location to server
         output.flush();
         myTurn = false; // not my turn anymore
      } // end if
   } // end method sendClickedSquare
   // set current Square
   public void setCurrentSquare( Square square )
      currentSquare = square; // set current square to argument
   } // end method setCurrentSquare
   // private inner class for the squares on the board
   private class Square extends JPanel
      private String mark; // mark to be drawn in this square
      private int location; // location of square
      public Square( String squareMark, int squareLocation )
         mark = squareMark; // set mark for this square
         location = squareLocation; // set location of this square
         addMouseListener(
            new MouseAdapter() {
               public void mouseReleased( MouseEvent e )
                  setCurrentSquare( Square.this ); // set current square
                  // send location of this square
                  sendClickedSquare( getSquareLocation() );
               } // end method mouseReleased
            } // end anonymous inner class
         ); // end call to addMouseListener
      } // end Square constructor
      // return preferred size of Square
      public Dimension getPreferredSize()
         return new Dimension( 30, 30 ); // return preferred size
      } // end method getPreferredSize
      // return minimum size of Square
      public Dimension getMinimumSize()
         return getPreferredSize(); // return preferred size
      } // end method getMinimumSize
      // set mark for Square
      public void setMark( String newMark )
         mark = newMark; // set mark of square
         repaint(); // repaint square
      } // end method setMark
      // return Square location
      public int getSquareLocation()
         return location; // return location of square
      } // end method getSquareLocation
      // draw Square
      public void paintComponent( Graphics g )
         super.paintComponent( g );
         g.drawRect( 0, 0, 29, 29 ); // draw square
         g.drawString( mark, 11, 20 ); // draw mark
      } // end method paintComponent
   } // end inner-class Square
} // end class TicTacToeClient

I'll look into doing it that way... One thing I don't understand is that when the winning player places it's final marker and gets the game over message the other player gets passed the Opponent moved message. So shouldn't I be able to pass a Game Over message to the other player after sending the Game Over message to the winning player? I'm not sure where in the code I'd need to put the output statement or what code I'd use to send it to the losing player instead of the winning player. I'm fairly new to threading and working on this for school, the book is not very much help in this area, so excuse my ignorance. Is it possible to send a message to the losing client right after sending one to the winning client after the main while loop exits around line 309 of TicTacToeServer.java? Or is this not possible because of how threading works?

Similar Messages

  • File Based Multithreaded Web Server Question

    Hi friends,
    I have the code of a simple File Based Multithreaded Web Server. I have been asked to add proper http/1.1 Keep-Alive behavior to it. As far as I understand it means to use the same socket for the request coming from the same client without opening a new socket for every request by it. I am unable to implement it. Any help would be greatly appreciated. The entire code is as below:
    package multithreadedwebserver.com;
    import java.io.*;
    import java.net.*;
    import java.util.*;
    /** This Class declares the general and HTTP constants
    * and defines general static methods:
    class Constants {
    /** 2XX: generally "OK" */
    public static final int HTTP_OK = 200;
    public static final int HTTP_CREATED = 201;
    public static final int HTTP_ACCEPTED = 202;
    public static final int HTTP_NOT_AUTHORITATIVE = 203;
    public static final int HTTP_NO_CONTENT = 204;
    public static final int HTTP_RESET = 205;
    public static final int HTTP_PARTIAL = 206;
    /** 3XX: relocation/redirect */
    public static final int HTTP_MULT_CHOICE = 300;
    public static final int HTTP_MOVED_PERM = 301;
    public static final int HTTP_MOVED_TEMP = 302;
    public static final int HTTP_SEE_OTHER = 303;
    public static final int HTTP_NOT_MODIFIED = 304;
    public static final int HTTP_USE_PROXY = 305;
    /** 4XX: client error */
    public static final int HTTP_BAD_REQUEST = 400;
    public static final int HTTP_UNAUTHORIZED = 401;
    public static final int HTTP_PAYMENT_REQUIRED = 402;
    public static final int HTTP_FORBIDDEN = 403;
    public static final int HTTP_NOT_FOUND = 404;
    public static final int HTTP_BAD_METHOD = 405;
    public static final int HTTP_NOT_ACCEPTABLE = 406;
    public static final int HTTP_PROXY_AUTH = 407;
    public static final int HTTP_CLIENT_TIMEOUT = 408;
    public static final int HTTP_CONFLICT = 409;
    public static final int HTTP_GONE = 410;
    public static final int HTTP_LENGTH_REQUIRED = 411;
    public static final int HTTP_PRECON_FAILED = 412;
    public static final int HTTP_ENTITY_TOO_LARGE = 413;
    public static final int HTTP_REQ_TOO_LONG = 414;
    public static final int HTTP_UNSUPPORTED_TYPE = 415;
    /** 5XX: server error */
    public static final int HTTP_SERVER_ERROR = 500;
    public static final int HTTP_INTERNAL_ERROR = 501;
    public static final int HTTP_BAD_GATEWAY = 502;
    public static final int HTTP_UNAVAILABLE = 503;
    public static final int HTTP_GATEWAY_TIMEOUT = 504;
    public static final int HTTP_VERSION = 505;
    /* the Web server's virtual root directory */
    public static File root;
    static PrintStream log = null;
    /* Configuration information of the Web server is present
    * in this props object
    protected static Properties props = new Properties();
    /* timeout on client connections */
    static int timeout = 0;
    /* maximum number of worker threads */
    static int workerThreads = 5;
    /* General method for printing strings */
    static void printString(String s) {
    System.out.println(s);
    /* print logs to the log file */
    static void log(String s) {
    synchronized (log) {
    log.println(s);
    log.flush();
    /* print to the log file */
    static void printProperties() { 
    printString("\n");
    printString("#####################################################################");
    printString("\n");
    printString("Web server's virtual root directory= "+root);
    printString("Timeout on client connections in milliseconds= "+timeout);
    printString("Number of Worker Threads= "+workerThreads);
    printString("\n");
    printString("#####################################################################");
    printString("\n\n");
    printString("********************WEBSERVER STARTED SUCCESSFULLY********************\n");
    /* load server.properties from java.home */
    static void loadServerConfigurationProperties() throws IOException {
    File f = new File(System.getProperty("java.home")+"\\lib\\"+"server.properties");
    if (f.exists()) {
    InputStream is =new BufferedInputStream(new FileInputStream(f));
    props.load(is);
    is.close();
    String r = props.getProperty("root");
    if (r != null) {
    root = new File(r);
    if (!root.exists()) {
    throw new Error(root + " Server Root Directory does not exist");
    r = props.getProperty("timeout");
    if (r != null) {
    timeout = Integer.parseInt(r);
    r = props.getProperty("workerThreads");
    if (r != null) {
    workerThreads = Integer.parseInt(r);
    r = props.getProperty("log");
    if (r != null) {
    log = new PrintStream(new BufferedOutputStream(
    new FileOutputStream(r)));
    /* Assign default values to root, timeout,
    * workerThreads and log if the same have
    * not been specified in the server.propwerties file
    if (root == null) {   
    root = new File(System.getProperty("user.dir"));
    if (timeout <= 1000) {
    timeout = 5000;
    if (workerThreads > 25) {
    printString("\n");
    printString("#####################################################################");
    printString("\n");
    printString("Too many Threads!!!Maximum number of Worker Threads can be 15 only");
    printString("\n");
    printString("#####################################################################");
    workerThreads = 15;
    if (log == null) {
    log = System.out;
    public class WebServer extends Constants {
    /* Specifying Default port for listening the requests */
    static int port = 8080;
    /* The Vector class implements a growable array of objects.
    * Like an array, it contains components that can be accessed using an integer index.
    * The size of a Vector can grow or shrink as needed to accommodate adding and
    * removing items after the Vector has been created.
    * The workerThreads are added to the Vector object threads where the worker threads stand idle
    * Vector is used since it is synchronized
    static Vector threads = new Vector();
    public static void main(String[] userSpecifiedPort) throws Exception {
    if (userSpecifiedPort.length > 0) {
    port = Integer.parseInt(userSpecifiedPort[0]);
    loadServerConfigurationProperties();
    printProperties();
    /* Instantiate ThreadPoool class and call
    * the createThreadPool() method on threadPool object
    ThreadPool threadPool= new ThreadPool();
    threadPool.createThreadPool();
    /* This class implements java.lang.Runnable.
    * It runs in a worker thread to process the request and serve files to the clients.
    class Worker extends WebServer implements Runnable {
    static final byte[] EOL = {(byte)'\r', (byte)'\n' };
    final static int BUFFER_SIZE = 2048;
    /* A byte array buffer to read and write files.
    * Memory is allocated to it once in the construtor of the class Worker
    * and reused thereafter
    byte[] buffer;
    /* Socket for the client being handled */
    private Socket socket;
    Worker() {
    buffer = new byte[BUFFER_SIZE];
    socket = null;
    synchronized void setSocket(Socket socket) {
    this.socket = socket;
    notify();
    public synchronized void run() {
    do {
    if (socket == null) {
    /* Wait */
    try {
    wait();
    } catch (InterruptedException e) {
    continue;
    try {
    handleClientRequest();
    } catch (Exception e) {
    e.printStackTrace();
    socket = null;
    Vector pool = WebServer.threads;
    synchronized (pool) {
    /* When the request is complete add the worker thread back
    * into the pool
    pool.addElement(this);
    }while(true);
    void handleClientRequest() throws IOException {
    InputStream is = new BufferedInputStream(socket.getInputStream());
    PrintStream ps = new PrintStream(socket.getOutputStream());
    /* we will only block in read for this many milliseconds
    * before we fail with java.io.InterruptedIOException,
    * at which point we will abandon the connection.
    socket.setSoTimeout(WebServer.timeout);
    socket.setTcpNoDelay(true);
    /* Refresh the buffer from last time */
    for (int i = 0; i < BUFFER_SIZE; i++) {
    buffer[i] = 0;
    try {
    /* We will only support HTTP GET/HEAD */
    int readBuffer = 0, r = 0;
    boolean endOfLine=false;
    while (readBuffer < BUFFER_SIZE) {
    r = is.read(buffer, readBuffer, BUFFER_SIZE - readBuffer);
    if (r == -1) {
    /* EOF */
    return;
    int i = readBuffer;
    readBuffer += r;
    for (; i < readBuffer; i++) {
    if (buffer[i] == (byte)'\n' || buffer[i] == (byte)'\r') {
    /* read one line */
    endOfLine=true;
    break;
    if (endOfLine)
    break;
    /*Checking for a GET or a HEAD */
    boolean doingGet;
    /* beginning of file name */
    int index;
    if (buffer[0] == (byte)'G' &&
    buffer[1] == (byte)'E' &&
    buffer[2] == (byte)'T' &&
    buffer[3] == (byte)' ') {
    doingGet = true;
    index = 4;
    } else if (buffer[0] == (byte)'H' &&
    buffer[1] == (byte)'E' &&
    buffer[2] == (byte)'A' &&
    buffer[3] == (byte)'D' &&
    buffer[4] == (byte)' ') {
    doingGet = false;
    index = 5;
    } else {
    /* This method is not supported */
    ps.print("HTTP/1.0 " + HTTP_BAD_METHOD +
    " unsupported method type: ");
    ps.write(buffer, 0, 5);
    ps.write(EOL);
    ps.flush();
    socket.close();
    return;
    int i = 0;
    /* find the file name, from:
    * GET /ATG/DAS6.3.0/J2EE-AppClients/index.html HTTP/1.0
    * extract "/ATG/DAS6.3.0/J2EE-AppClients/index.html "
    for (i = index; i < readBuffer; i++) {
    if (buffer[i] == (byte)' ') {
    break;
    String filename = (new String(buffer, 0, index,
    i-index)).replace('/', File.separatorChar);
    if (filename.startsWith(File.separator)) {
    filename = filename.substring(1);
    File targ = new File(WebServer.root, filename);
    if (targ.isDirectory()) {
    File ind = new File(targ, "index.html");
    if (ind.exists()) {
    targ = ind;
    boolean fileFound = printHeaders(targ, ps);
    if (doingGet) {
    if (fileFound) {
    sendResponseFile(targ, ps);
    } else {
    fileNotFound(targ, ps);
    } finally {  
    // socket.close();
    System.out.println("Connection Close nahi kiya");
    boolean printHeaders(File targ, PrintStream ps) throws IOException {
    boolean ret = false;
    int responseStatusCode = 0;
    if (!targ.exists()) {
    responseStatusCode = HTTP_NOT_FOUND;
    ps.print("HTTP/1.0 " + HTTP_NOT_FOUND + " not found");
    ps.write(EOL);
    ret = false;
    } else {
    responseStatusCode = HTTP_OK;
    ps.print("HTTP/1.0 " + HTTP_OK+" OK");
    ps.write(EOL);
    ret = true;
    log("From " socket.getInetAddress().getHostAddress()": GET " +
    targ.getAbsolutePath()+"-->"+responseStatusCode);
    ps.print("Server: Simple java");
    ps.write(EOL);
    ps.print("Date: " + (new Date()));
    ps.write(EOL);
    if (ret) {
    if (!targ.isDirectory()) {
    ps.print("Content-length: "+targ.length());
    ps.write(EOL);
    ps.print("Last Modified: " + (new
    Date(targ.lastModified())));
    ps.write(EOL);
    String name = targ.getName();
    int ind = name.lastIndexOf('.');
    String ct = null;
    if (ind > 0) {
    ct = (String) map.get(name.substring(ind));
    if (ct == null) {
    ct = "unknown/unknown";
    ps.print("Content-type: " + ct);
    ps.write(EOL);
    } else {
    ps.print("Content-type: text/html");
    ps.write(EOL);
    return ret;
    void fileNotFound(File targ, PrintStream ps) throws IOException {
    ps.write(EOL);
    ps.write(EOL);
    ps.println("The requested file could not be found.\n");
    void sendResponseFile(File targ, PrintStream ps) throws IOException {
    InputStream is = null;
    ps.write(EOL);
    if (targ.isDirectory()) { ;
    listDirectory(targ, ps);
    return;
    } else {
    is = new FileInputStream(targ.getAbsolutePath());
    try {
    int n;
    while ((n = is.read(buffer)) > 0) {
    ps.write(buffer, 0, n);
    } finally {
    is.close();
    /* mapping file extensions to content-types */
    static java.util.Hashtable map = new java.util.Hashtable();
    void listDirectory(File dir, PrintStream ps) throws IOException {
    ps.println("<TITLE>Multithreaded Webserver</TITLE><P>");
    ps.println("<html><body align=center>");
    ps.println("<center><h3><font color=#9999CC>Simple File Based MultiThreaded WebServer</font></h3></center>");
    ps.println("<table border=1 align=center>");
    ps.println("<tr bgcolor=#9999CC><td width=100% height=100% align=center><h3>Directory Listing</h3></td>");
    ps.println("<td width=40% height=40% align=center><h3>Type</h3></td>");
    String[] list = dir.list();
    for (int i = 0; list != null && i < list.length; i++) {
    File f = new File(dir, list);
    if (f.isDirectory()) {
    ps.println("<tr><td>");
    ps.println("<font size=\""+"2"+"\"face=\""+"Verdana"+"\"> <A HREF=\""+list[i]+"/\">"+list[i]+"</A></font><a href=\""+list[i]+"/\"></a>\n<BR></td>");
    ps.println("<td align=center><a href=\""+list[i]+"/\"><img src=\""+"/images/folder.jpg"+"\"></img></a>");
    ps.println("</td");
    ps.println("</tr>");
    } else {
    ps.println("<tr><td>");
    ps.println("<font size=\""+"2"+"\" face=\""+"Verdana"+"\"></A> <A HREF=\""+list[i]+"\">"+list[i]+"</A></font><A HREF=\""+list[i]+"\"></A>\n<BR></td>");
    ps.println("<td align=center><a href=\""+list[i]+"/\"><img src=\""+"/images/file.gif"+"\"></img></a>");
    ps.println("</tr>");
    ps.println("</table>");
    ps.println("<P><HR><I><font color=blue>"+(new Date())+"</font></I>");
    ps.println("<I><font color=blue>Copyright to HCL Technology Ltd</font></I>");
    ps.println("<I><font color=blue>Author Vivek Kumar Sinha</font></I>");
    ps.println("</body></html>");
    The ThreadPool class contains a Vector of WorkerThread objects.
    These objects are the individual threads that make up the pool.
    The WorkerThread objects will start at the time of their construction.
    If there are more HTTP requests than there are WorkerThreads,
    the extra requests will backlog until WorkerThreads free up.
    class ThreadPool extends WebServer{
    void createThreadPool(){
    for (int i = 1; i <= workerThreads; ++i) {
    Worker w = new Worker();
    Thread t=new Thread(w, "Worker Thread No."+i);
    t.start();
    /* Uncomment to check the number of worker threads running */
    // printString("Worker Thread No."+i+" Started");
    threads.addElement(w);
    try{
    ServerSocket serversocket = new ServerSocket(port);
    do {
    Socket socket = serversocket.accept();
    Worker w = null;
    synchronized (threads) {
    if (threads.isEmpty()) {
    /* Do nothing */
    } else {
    w = (Worker) threads.elementAt(0);
    threads.removeElementAt(0);
    w.setSocket(socket);
    } while (true);
    } catch (IOException e) {
    e.printStackTrace();

    Thank you for Welcoming me!!! I am very new to this forum so din't have this idea.
    I am unable to add the keep alive behavior . I don't have problem with any part of the code. The problem is i don't know how to make that enhancement in the existing code.
    Regards

  • Design Pattern for multithreaded client server program

    I asked this question in another post, but with other stuff, so I'll distill this one.
    I am creating a multi-threaded client server program (just for learning - a chat program at this point). I built the server and client in swing, and I'm wondering what the best design pattern is for this setup. Right now all the swing stuff is in the MyServer class. In that class I have a loop accepting client connections to the serverSocket and creating a new MyServerThread (threaded client connection).
    The problem is that all the work of creating input streams, interacting with the server, all that stuff is done in the MyServerThread class, but I want that text to be written up to the Swing objects - which is in the MyServer class. So right now in the MyServerThread class I pass the MyServer object into it, but I'm not sure if that is really the most robust thing to do. Does anybody have any suggestions as to how this should be done. If somebody has an article they'd like to point to I'll check it out too. But if it's just the run-of-the-mill multithreaded client-server article, I've read alot and most don't specifically address my question.

    Thanks for the reply Kaj, and I think I'll keep my design for now, since it's just quick and dirty. I've read the MVC concept a while ago and I'll revisit it again when I get more serious. But I have a question, why should I be using a callback interface, why an interface at all? And then make MyServer implement that interface...why not just pass MyServer to the thread object? Or is there something down the line that I did not forsee?

  • How to fix "server problem" error message when trying to use PhoneGap build service.

    I have a site that is now optimized for mobile devices and want to use the PhoneGap Build service in Dreamweaver CS6 to make a native app.  Unfortunately, I keep getting the "We seem to be having server problems." error message when I try to create a new project.  I did notice that the configuration file was created at the site root.  I've seen a few other similar threads on this, but no solution.  I've checked on any firewall issues (none) and know that the PhoneGap server is not down.  The problem is on my end.
    Thanks,
    Loren

    Not an answer to the server problem, but I have posted the PhoneGap Build process here: http://forums.adobe.com/message/4669054#4669054. It might help anyone still having problems.

  • [Fwd: Starting Managed server problem ......]

    Forwarding to the security news group...
    -------- Original Message --------
    Subject: Starting Managed server problem ......
    Date: 1 Jun 2004 23:02:53 -0700
    From: Sameer <barsatkiraat2001>
    Newsgroups: weblogic.developer.interest.management
    Hi All,
    I need you guy's help in this regard, that I am using solaris 8 and
    installed Weblogic8.1 Server.
    My Scenario is;
    Have configured Admin Server and Managed server with nodemanager on one
    unix machine.
    So, what am facing the problem;
    I am not able to get run Managed server after starting the nodemanager
    and admin server, getting the error in nodemanager logs that is :
    <Jun 2, 2004 9:44:26 AM GMT 04:00> <Warning> <Security> <BEA-090482>
    <BAD_CERTIFICATE alert was received from PortalQA - 10.12.10.94. Check
    the peer to determine why it rejected the certificate chain (trusted CA
    configuration, hostname verification). SSL debug tracing may be required
    to determine the exact reason the certificate was rejected.>
    And in Admin Server logs it's saying;
    <Jun 2, 2004 9:44:26 AM GMT 04:00> <Warning> <Security> <BEA-090504>
    <Certificate chain received from PortalQA - 10.12.10.94 failed hostname
    verification check. Certificate contained AdminQA but check expected
    PortalQA>
    The WebLogic Server did not start up properly.
    Exception raised:
    'weblogic.management.configuration.ConfigurationException: Due to faulty
    SSL configuration, this server is unable to establish a connection to
    the node manager.'
    <Jun 2, 2004 9:44:26 AM GMT 04:00> <Warning> <NodeManager> <BEA-300038>
    <The node manager is unable to monitor this server. Could not create an
    SSL connection to the node manager. Reason :
    [Security:090504]Certificate chain received from PortalQA - 10.12.10.94
    failed hostname verification check. Certificate contained AdminQA but
    check expected PortalQA>
    Reason: weblogic.management.configuration.ConfigurationException: Due to
    faulty SSL configuration, this server is unable to establish a
    connection to the node manager.
    <Jun 2, 2004 9:44:26 AM GMT 04:00> <Emergency> <WebLogicServer>
    <BEA-000342> <Unable to initialize the server:
    weblogic.management.configuration.ConfigurationException: Due to faulty
    SSL configuration, this server is unable to establish a connection to
    the node manager.>
    If some one can help me, I do appreciate in all due respect.
    Sameer.

    Hello Satya/All,
    I'm also experiencing the exact problem you are facing. It would be great if
    somebody could help in this regard at the earliest.
    Thanks, senthil
    Satya Ghattu <[email protected]> wrote:
    Forwarding to the security news group...
    -------- Original Message --------
    Subject: Starting Managed server problem ......
    Date: 1 Jun 2004 23:02:53 -0700
    From: Sameer <barsatkiraat2001>
    Newsgroups: weblogic.developer.interest.management
    Hi All,
    I need you guy's help in this regard, that I am using solaris 8 and
    installed Weblogic8.1 Server.
    My Scenario is;
    Have configured Admin Server and Managed server with nodemanager on one
    unix machine.
    So, what am facing the problem;
    I am not able to get run Managed server after starting the nodemanager
    and admin server, getting the error in nodemanager logs that is :
    <Jun 2, 2004 9:44:26 AM GMT 04:00> <Warning> <Security> <BEA-090482>
    <BAD_CERTIFICATE alert was received from PortalQA - 10.12.10.94. Check
    the peer to determine why it rejected the certificate chain (trusted
    CA
    configuration, hostname verification). SSL debug tracing may be required
    to determine the exact reason the certificate was rejected.>
    And in Admin Server logs it's saying;
    <Jun 2, 2004 9:44:26 AM GMT 04:00> <Warning> <Security> <BEA-090504>
    <Certificate chain received from PortalQA - 10.12.10.94 failed hostname
    verification check. Certificate contained AdminQA but check expected
    PortalQA>
    The WebLogic Server did not start up properly.
    Exception raised:
    'weblogic.management.configuration.ConfigurationException: Due to faulty
    SSL configuration, this server is unable to establish a connection to
    the node manager.'
    <Jun 2, 2004 9:44:26 AM GMT 04:00> <Warning> <NodeManager> <BEA-300038>
    <The node manager is unable to monitor this server. Could not create
    an
    SSL connection to the node manager. Reason :
    [Security:090504]Certificate chain received from PortalQA - 10.12.10.94
    failed hostname verification check. Certificate contained AdminQA but
    check expected PortalQA>
    Reason: weblogic.management.configuration.ConfigurationException: Due
    to
    faulty SSL configuration, this server is unable to establish a
    connection to the node manager.
    <Jun 2, 2004 9:44:26 AM GMT 04:00> <Emergency> <WebLogicServer>
    <BEA-000342> <Unable to initialize the server:
    weblogic.management.configuration.ConfigurationException: Due to faulty
    SSL configuration, this server is unable to establish a connection to
    the node manager.>
    If some one can help me, I do appreciate in all due respect.
    Sameer.

  • Photoshop CS2: name server problem: Is there a solution?

    Hi!
    I have Photoshop CS2. I can't start the program anymore because of the already well known name server problem... (DEAR ADOBE!! HOW COULD YOU!!! )
    Now, what can I do? As far as I know I purchased the software for an unlimited amount of time (thanks to the fact that there weren't any clouds, halleluja!)
    Can anybody help me, please? Is there a way "around"?
    Thanks a lot!!!
    Christiane

    Error: Activation Server Unavailable | CS2, Acrobat 7, Audition 3

  • I keep getting Server problems when trying to sign into messages

    Hi can anyone help, I have an Imac, and Lion  X 10.7.3, I have downloaded Messages Beta, evertytime I try to register it will not let me, telling me Server Problems try again later? Has anyone come across this? And can anyone help? Thank you.

    Hi can anyone help, I have an Imac, and Lion  X 10.7.3, I have downloaded Messages Beta, evertytime I try to register it will not let me, telling me Server Problems try again later? Has anyone come across this? And can anyone help? Thank you.

  • I recently updated Firefox and now it will not open. It says there is a proxy server problem.

    I was requested to update the program and now it says there is a proxy server problem.

    Hi:
    You can try this COMPRESSOR TROUBLESHOOTING document:
    http://docs.info.apple.com/article.html?artnum=302845
    Hope it helps !
      Alberto

  • Firefox periodically drops my Verizon/Yahoo email site indicating it cannot find the server. Verizon alledges there are no server problems.

    My email page will crash and the message received is:Firefox can't find the server at us.mc844.mail.yahoo.com. Repeated reloading does not help. After a period of time from 5 minutes to an hour the site can be accessed and is Ok for several days. The the problem reoccurs several times in the same day. When my email provider is contacted they indicate no server problems.

    Report your error messages so your peers, like me, can make suggestions..
    Official recommendations are on http://help.yahoo.com/l/us/verizon/mail/ymail/basics/mail-12859445.html NOTE THE URL's Stick with them if using YAHOO.  I have not found a newer recommendation for pop.yahoo.verizon.net that you mention, and the help page was updated this month.
    Note some have had trouble with missing intermediate certificates so get encryption errors.  Shouldn't happen (except if you are missing the root certificate, which is your responsibility),  but can be fixed by installing manually.
    Some have reported needing to specify [email protected] rather than just userid, I believe on the SMTP side.  Normally you specify only userid and password without the @verizon.net.

  • Design question for database connection in multithreaded socket-server

    Dear community,
    I am programming a multithreaded socket server. The server creates a new thread for each connection.
    The threads and several objects witch are instanced by each thread have to access database-connectivity. Therefore I implemented factory class which administer database connection in a pool. At this point I have a design question.
    How should I access the connections from the threads? There are two options:
    a) Should I implement in my server class a new method like "getDatabaseConnection" which calls the factory class and returns a pooled connection to the database? In this case each object has to know the server-object and have to call this method in order to get a database connection. That could become very complex as I have to safe a instance of the server object in each object ...
    b) Should I develop a static method in my factory class so that each thread could get a database connection by calling the static method of the factory?
    Thank you very much for your answer!
    Kind regards,
    Dak
    Message was edited by:
    dakger

    So your suggestion is to use a static method from a
    central class. But those static-methods are not realy
    object oriented, are they?There's only one static method, and that's getInstance
    If I use singleton pattern, I only create one
    instance of the database pooling class in order to
    cionfigure it (driver, access data to database and so
    on). The threads use than a static method of this
    class to get database connection?They use a static method to get the pool instance, getConnection is not static.
    Kaj

  • Mail Server Problem

    The mail server problem has been resolved, mail is working as designed....yeah!!

    silly discusting board, I've got 3 replies in my email but it's not showing here ...
    anyway, this time I found after some chasing my tail .... that the mail preferences had wiped my password and I needed to reinstall it, then instruct it to go online and some other click stuff ....
    and it seems to be ok now ....
    but each round in past 2 weeks has been different "fix" .... or wait ....
    sorry for anyone without master email for 5 days, that's just not right ....
    I'm afraid that as apple starts "giving away" email accounts to build the cloud into something much bigger than the mobile me was .... that their folo up will fail and we will find ourselves not with the same apple durability / consistency but with the "hey it's free" attitude ....
    let's see

  • Email server problem - failed to connect to server

    Since Friday 27th August I've been having trouble connecting to the email server for my BT Yahoo account. It simply can't find the server, even though none of the account settings have changed and it has worked fine for years. Weirdly, sometimes it works and emails come through (so the settings are obviously fine) but then it will stop working for no apparent reason. I use Thunderbird as my email client, but I tested the account in Outlook Express and it gives the same error. The account works fine over webmail, and through my iPhone, however.
    It seems like this is a DNS error rather than software related - is there anything BT-related that could be causing this, or any simple fixes? I've tried rebooting the HomeHub but that doesn't seem to have made a difference. I work from home, so this is a really annoying problem.

    Lynx wrote:
    Interesting - we have exactly the same problem. Haven't been able to download for days. This has happened with two different computers with different anti-virus systems - so one assumes it's not suddenly that. I can access my e-mail online and reply (having to bcc myself, so when it does eventually work I have copies on my outlook express. It was working perfectly one night and the next morning just stopped - nothing happened in between.
    I have tried to find out what the error number means, but no-one - not even BT's Help section - seem to have the solution. Have you ever seen the Eddie Izzard sketch on YouTube? This is definately one of those moments!
    If you find a solution - would really appreciate you posting it on here, so I can fix mine. Will do the same for youi.
    Hi.
    This sort of problem is hard to determine. It could be a few things, including a corruption of the mail account (which can last for a short time or a number of days), it could be a local problem - which you've ruled out by the different computer check, or perhaps a "stuck" email - say one which is spam/virus attached and the online checking systems failing to pass through it, or possibly a stale IP address.
    The latter 2 are easy to check, the first via webmail and see if there is anything near the "top" of the list that may cause a problem, moving to a new folder, and try again. The last can be tried by power cycling the router to get a new IP address. Disconnect the broadband and router for say 15 minutes and then reconnect to try again.
    If there was a major server problem, there would be lots more complaints.
    http://www.andyweb.co.uk/shortcuts
    http://www.andyweb.co.uk/pictures

  • I have just installed Lion OS and Face Time encounters server problems on sign up. I have sought the firewall problem without success and even temporarily turned off firewall with no success.

    I have just installed Lion OS and Face Time encounters server problems on sign up. I have sought to rectify the firewall problem without success and even temporarily turned off firewall with no success. Any ideas?

    Some folks have discovered that changing their DNS service fixes FaceTime connection issues.
    The ideal way is to configure your modem/router with DNS service, but often settings in System Preferences/Network/Advanced/DNS on your Mac will override the router settings. Try either of these;
    OpenDNS
    208.67.222.222, 208.67.220.220
    Google Public DNS
    8.8.8.8, 8.8.4.4

  • TS4002 Anybody having icloud server problems today? No incoming mail

    Dear all,
    I'm not receiving any mail guz Icloud tells me it has a server problem. I can send mail but not receive any. I can send myself a message using gmail sending it to my own gmail adres and I receive in my Mail program, no problem, it's just the ME account that does not work on any of my apple devices. I've checked the setting in the prefference from the Mail program, they all seam normal......ANY tips???
    Thank you so much,
    Simon

    Most inconvenient... trying to run a business and I made the mistake of using my me.com acct. for business rather than the old Yahoo acct.   I haven't been able to receive email all day either.
    Seeing that it's affecting less than 1% of it's customers, really is annoying for some reason. 

  • Could Not Sign In:  A server problem is blocking Apple ID sign in.  Try signing in later.

    After a successful iOS 5 upgrade to my iPhone 3GS, I began going through the setup wizard the phone takes you through upon initial use.  However, I'm unable to make it past the part where you are supposed to "Sign In with an Apple ID".  The steps to reproduce the problem are:
    Click "Sign In with an Apple ID".
    Per the "Have MobileMe and an ITunes Account?" instructions, I opt to type in my MobileMe e-mail address (e.g. [email protected]) and password.
    Click "Next".
    Specify birthday.
    Click "Next".
    Click "Agree".
    Click "Agree" on popup.
    A popup error is produced which reads "Could Not Sign In:  A server problem is blocking Apple ID sign in.  Try signing in later.".
    Click "OK" which takes you back to the initial sign in screen.
    I have tried logging in since 2am ET.  It is now 8:17am ET.  The server should not be down for over 6 hours.  Any ideas?
    Thanks in advance for any assistance offered!

    Hi Natalie,
    I was able to workaround this issue by clicking the "Skip" option on the first screen.  Afterwards, I went back and manually entered my me.com Apple ID in Settings | iCloud and my iTunes Apple ID in Settings | Store.  Doing it this way doesn't ask you to enter your birthday and I haven't yet found where that is supposed to be set.  However, everything appears to be working correctly without it.  Hope this helps!
    Brad

Maybe you are looking for