Multi thread Server
Hello,
I have had this code working on one server and one client, both other clients cannot join the connection at the same time although I have created threads. I have also passed by reference the Socket connection in the constructor of the inner class that extends Thread so there should be more than one client at a time that the server can connect. The class that extends Thread does not seem to be giving the System.out.prints commands either. I am trying to find what I can do about its structure.
Thanks,
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import java.util.Formatter;
import java.util.Scanner;
publicclass Serverextends JFrame
{
private JTextField enterField;// inputs message from user
private JTextArea displayArea;// display information to user
private ObjectOutputStream output;// output stream to client
private ObjectInputStream input;// input stream from client
private ServerSocket server;// server socket
private Socket connection;// connection to client
privateint counter = 1;// counter of number of connections
private Player[] players;
private Scanner inputs;
private Formatter outputs;
// set up GUI
public Server()
{
super("Server" );
enterField =new JTextField();// create enterField
enterField.setEditable(false );
enterField.addActionListener(
new ActionListener()
{
// send message to client
publicvoid actionPerformed( ActionEvent event )
{
sendData( event.getActionCommand() );
enterField.setText("" );
}// end method actionPerformed
}// end anonymous inner class
);// end call to addActionListener
add( enterField, BorderLayout.NORTH );
displayArea =new JTextArea();// create displayArea
add(new JScrollPane( displayArea ), BorderLayout.CENTER );
setSize( 300, 150 );// set size of window
setVisible(true );// show window
}// end Server constructor
// set up and run server
publicvoid runServer()
{
try// set up server to receive connections; process connections
{
server =new ServerSocket( 12345, 100 );// create ServerSocket
while (true )
{
try
{
waitForConnection();// wait for a connection
getStreams();// get input & output streams
processConnection();// process connection
}// end try
catch ( EOFException eofException )
{
displayMessage("\nServer terminated connection" );
}// end catch
finally
{
closeConnection();// close connection
counter++;
}// end finally
}// end while
}// end try
catch ( IOException ioException )
{
ioException.printStackTrace();
}// end catch
}// end method runServer
privateclass Playerextends Thread
{
private Socket connection;
public Player( Socket socket )
{
connection = socket;
System.out.print("This should be client Thread");
}
publicvoid run()
{
players =new Player [10];
for (int i = 0; i < players.length; i++)
{
players [i].start();
}
try
{
inputs =new Scanner (connection.getInputStream());
outputs =new Formatter (connection.getOutputStream());
}
catch (IOException ioException)
{
ioException.printStackTrace();
System.exit(1);
}
displayMessage ("Client is connected");
}
}
// wait for connection to arrive, then display connection info
privatevoid waitForConnection()throws IOException
{
displayMessage("Waiting for connection\n" );
connection = server.accept();// allow server to accept connection
displayMessage("Connection " + counter +" received from: " +
connection.getInetAddress().getHostName() );
}// end method waitForConnection
// get streams to send and receive data
privatevoid getStreams()throws IOException
{
// set up output stream for objects
output =new ObjectOutputStream( connection.getOutputStream() );
output.flush();// flush output buffer to send header information
// set up input stream for objects
input =new ObjectInputStream( connection.getInputStream() );
displayMessage("\nGot I/O streams\n" );
}// end method getStreams
// process connection with client
privatevoid processConnection()throws IOException
{
String message ="Connection successful";
sendData( message );// send connection successful message
// enable enterField so server user can send messages
setTextFieldEditable(true );
do// process messages sent from client
{
try// read message and display it
{
message = ( String ) input.readObject();// read new message
displayMessage("\n" + message );// display message
}// end try
catch ( ClassNotFoundException classNotFoundException )
{
displayMessage("\nUnknown object type received" );
}// end catch
}while ( !message.equals("CLIENT>>> TERMINATE" ) );
}// end method processConnection
// close streams and socket
privatevoid closeConnection()
{
displayMessage("\nTerminating connection\n" );
setTextFieldEditable(false );// disable enterField
try
{
output.close();// close output stream
input.close();// close input stream
connection.close();// close socket
}// end try
catch ( IOException ioException )
{
ioException.printStackTrace();
}// end catch
}// end method closeConnection
// send message to client
privatevoid sendData( String message )
{
try// send object to client
{
output.writeObject("SERVER>>> " + message );
output.flush();// flush output to client
displayMessage("\nSERVER>>> " + message );
}// end try
catch ( IOException ioException )
{
displayArea.append("\nError writing object" );
}// end catch
}// end method sendData
// manipulates displayArea in the event-dispatch thread
privatevoid displayMessage(final String messageToDisplay )
{
SwingUtilities.invokeLater(
new Runnable()
{
publicvoid run()// updates displayArea
{
displayArea.append( messageToDisplay );// append message
}// end method run
}// end anonymous inner class
);// end call to SwingUtilities.invokeLater
}// end method displayMessage
// manipulates enterField in the event-dispatch thread
privatevoid setTextFieldEditable(finalboolean editable )
{
SwingUtilities.invokeLater(
new Runnable()
{
publicvoid run()// sets enterField's editability
{
enterField.setEditable( editable );
}// end method run
}// end inner class
);// end call to SwingUtilities.invokeLater
}// end method setTextFieldEditable
}// end class Server

