Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

(Multithreaded Server) Multithreaded servers are quite popular today, especially

ID: 3544915 • Letter: #

Question

(Multithreaded Server) Multithreaded servers are quite popular today, especially because of the increasing use of multicore servers. Modify the simple server application presented in Section 27.6 to be a multithreaded server. Then use several client applications and have each of them connect to the server simultaneously. Use an ArrayList to store the client threads. ArrayList provides several meth- ods to use in this exercise. Method size determines the number of elements in an ArrayList. Method get returns the element in the location specified by its argument. Method add places its argument at the end of the ArrayList. Method remove deletes its argument from the ArrayList.


The server must contain a text based password file ("user name" & "password") . The client must pass a valid username and password to establish a connection with the Server.

Explanation / Answer

// Exercise 18.17 Solution: Server2.java
// Program sets up a Server that receives connections from clients, sends
// strings to the clients and receives string from the clients.
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class Server2 extends JFrame {
private JTextField enterField;
private JTextArea display;
private JScrollPane scroller;
private Vector clients;
private int numberOfClients;

// set up GUI
public Server2()
{
super( "Server" );
numberOfClients = 0;

// create enterField and register listener
enterField = new JTextField();
enterField.setEnabled( false );
enterField.addActionListener(

new ActionListener() { // anonymous inner class

// send message to clients
public void actionPerformed( ActionEvent event )
{
for ( int i = 0; i < clients.size(); i++ )
( ( ClientThread ) clients.elementAt( i ) ).sendData(
event.getActionCommand() );

enterField.setText( "" );
}
}
);

display = new JTextArea();
display.setEnabled( false );
scroller = new JScrollPane( display );

Container container = getContentPane();
container.add( enterField, BorderLayout.NORTH );
container.add( scroller, BorderLayout.CENTER );

setSize( 300, 150 );
setVisible( true );

} // end constructor Server2

// set up and run server
public void runServer()
{
// set up server and process connections
try {

// create ServerSocket
ServerSocket server = new ServerSocket( 5558, 100 );

clients = new Vector();

// accept connections and add ClientThreads to Vector
while ( true ) {
display.append( "Waiting for connection " );
numberOfClients++;
clients.add( new ClientThread( server.accept(),
display, numberOfClients ) );
( ( ClientThread ) clients.lastElement() ).start();

enterField.setEnabled( true );
}
}
// process problems with I/O
catch ( IOException ioException ) {
ioException.printStackTrace();
}

} // end method runServer

public static void main( String args[] )
{
Server2 application = new Server2();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
application.runServer();
}

// private inner class ClientThread manages each Client as a thread
private class ClientThread extends Thread {
private int clientNumber;
private Socket connection;
private ObjectOutputStream output;
private ObjectInputStream input;
private JTextArea display;

// set up a Client thread
public ClientThread( Socket socket, JTextArea display, int number )
{
this.display = display;
clientNumber = number;
connection = socket;

// obtain streams from Socket
try {
output = new ObjectOutputStream(
connection.getOutputStream() );
output.flush();

input = new ObjectInputStream( connection.getInputStream() );

sendData( "Connection successful" );

this.display.append( " Connection " +
clientNumber + " received from: " +
connection.getInetAddress().getHostName() + " " );
}

// process problems with IO
catch ( IOException ioException ) {
ioException.printStackTrace();
}

} // end constructor ClientThread

// send message to client
public void sendData( String message )
{
// send object to client
try {
output.writeObject( "SERVER>>> " + message );
output.flush();
display.append( " SERVER>>>" + message );
}

// process problems sending object
catch ( IOException ioException ) {
display.append( " Error writing object" );
}
}

// control thread's execution
public void run()
{
String message = null;

// process connection
try {

// read message from client
do {

try {
message = ( String ) input.readObject();
display.append( " " + message );
display.setCaretPosition( display.getText().length() );
}

// process problems reading from client
catch ( ClassNotFoundException classNotFoundException ) {
display.append( " Unknown object type received" );
}

} while ( !message.equals( "CLIENT>>> TERMINATE" ) );

display.append( " Client terminated connection" );
display = null;
}

// process problems with I/O
catch ( IOException ioException ) {
System.out.println( "Client terminated connection" );
}

// close streams and socket
finally {

try {
output.close();
input.close();
connection.close();
}
// process problems with I/O
catch ( IOException ioException ) {
ioException.printStackTrace();
}

clients.remove( this );
}

} // end method run

} // end class ClientThread

} // end class Server2