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,
LorenNot 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.
-
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!!!
ChristianeError: 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 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 -
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:
dakgerSo 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 -
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 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,
SimonMost 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. -
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
-
MBP13 - first lock-ups, now not even booting anymore
hi everyone, after last weeks itunes update (could be coincidence) i have experienced some lock-ups when using my mbp. first for only a few seconds, but they grew longer and longer to the point, where it was unusable. now it won't even boot. i get th
-
How can I get the iBook app on my Mac to backup ePubs I created with Pages on my iPad? Only seems to want to work with purchased books from the ibook store. The problem is, once I create a document in Pages and turn it into an ePub to be opened in iB
-
Wireless-N hardware and software issues
Yep the 300N gear goes back to BBuy tomorrow. I purchased a V1 of the wrt54G hardware almost 3 years ago, it died last week. Figured I’d buy the latest and greatest and be all set for another couple of years. Well I’ve had similar problems as the pos
-
AEBS Erratic behavior when connecting to attached USB Drives in XP
I have the old 10 100 version of the AEBS. I have always had problems with connecting to the attached USB (3) drives on a powered USB adapter. I have spent hours on the phone with Apple Support and eventually Apple released new firmware for the AEBS.
-
Dyanmic display of the Image Link URL
I have a typical report requirement for which I have googled but didnot get the proper solution. The report contains two columns , OrderId (Datatype Integer) and CustomerName . OrderId CustomerName 123 xyz 234 abc 345 pqr 456 klm The