Building a Multithreaded Server with Sockets


The server program in Listings 11.7 and 11.8 handles one client. How do you manage many client requests on the same port, which means several clients are trying to connect to the same ServerSocket object? In Java, you create threads, one for each client. Remember that the CPU does one thing at a time. If all threads run at perfect efficiency, completing 10 threads, for example, takes the same amount of time no matter what order the threads are in. Of course, threads, like connections, have slow moments. Taking up the slack in one thread with part of another thread reduces the total time for all 10. The more complicated a thread is, the more uneven its use of the CPU. Client/server software is complicated and uneven . Optimizing CPU use by swapping which connection is actually using the CPU at a given moment is a great idea.

The operating system can switch between different threads quickly, at thousands of times per second. Like an object, a thread is really a sequence of execution steps. So a thread uses the CPU for a while (thread one) and then gets booted off. The system saves registers, stacks, and queues associated with that thread into a so-called process control block. Then another thread (thread two) uses the CPU, and so on. Eventually, thread one has another turn , and the CPU resumes where that thread left off by resuming thread execution based on what's in the process control block. This swapping between threads is called multithreaded operation .

Currently, if you open a command prompt and run HusbandClient , it works fine. If you open a second command prompt and try to run HusbandClient , however, it freezes . To fix this problem, you need to make the server multithreaded. First, add another class, as shown in Listing 11.9. This class is similar to Listing 11.7 except that you add the capability for WifeServer to handle multiple HusbandClient s that make connections with WifeServer simultaneously .

Listing 11.9 Adding a Multithreaded Super Class
 import java.net.*; import java.io.*; //this class creates a separate thread for each //instance of HusbandClient. This makes the //server multiuser capable. public class WifeMultithreadedServer {    public static void main(String[] args) throws IOException {       boolean listening = true;       int PortNumber = 5108; //her ATM password       ServerSocket wifeSocket = null;       WifeThread wifeThread = null;       try       {          wifeSocket = new ServerSocket(PortNumber);       } catch (IOException e)       {         System.err.println("Port " + PortNumber + " not available." );          System.exit(1);       }       while (listening)       {  //each instance of HusbandClient gets          //its own WifeThread, which creates          //a socket connection with WifeServer.          new WifeThread(wifeSocket.accept()).start();       }       wifeSocket.close();    } } 

Listing 11.9 is the new class HusbandClient will connect to. This class acts like a server manager. When it gets a request for a connection, it spawns a new thread and hands the connection off to it, so that instance of the client is connected to the newly created thread ( WifeThread ). Isn't this fun? Next, you need to alter the previous WifeServer so that it can be a single thread, as shown in Listing 11.10. After that is accomplished, you have converted the single-threaded server that services only one socket connection into a multithreaded server that can handle multiple connections with clients simultaneously.

Listing 11.10 Making the Server Multithreaded
 import java.net.*; import java.io.*; /* You need to convert the single-threaded server that services only one socket connection into a multithreaded server that can handle multiple connections with clients simultaneously. By extending Thread, this class can now be handled as a single thread by WifeMultithreadedServer, which spawns a separate instance of WifeThread for every new connection made by each HusbandClient instance. */ public class WifeThread extends Thread {    private Socket wifeSocket = null;    public WifeThread(Socket socket)    {       super("WifeThread");       this.wifeSocket = socket;    }    public void run()    {       try       {          PrintWriter out =                   new PrintWriter(wifeSocket.getOutputStream(), true);          BufferedReader in = new BufferedReader(                            new InputStreamReader(                            wifeSocket.getInputStream()));          String husbandSays, wifeSays;          Wife wife = new Wife();          wifeSays = wife.answer(null);          out.println(wifeSays);          while ((husbandSays = in.readLine()) != null)          {             wifeSays = wife.answer(husbandSays);             out.println(wifeSays);             if (wife.turnOff)             {                break;             }          }          out.close();          in.close();          wifeSocket.close();       } catch (IOException e)       {          System.out.println(e);       }    } } 

Note that the new WifeMultithreadedServer calls the public WifeThread(Socket socket) constructor added in Listing 11.10 to create threads. There is only one other difference: The main method of the WifeServer class was replaced with the run method of the WifeThread class. Every application needs a main method, but every thread must have a run method. The Wife class is unchanged.

Your multithreaded server is finished. To try it out, compile the WifeThread class first. (The Wife class should still be at the bottom of file so that it gets compiled at the same time.) Next, compile the WifeMultithreadedServer class and run it. Then open three command prompts and run an instance of HusbandClient (which was not changed) in each. All three will work now because your new multithreaded server can handle numerous clients simultaneously. Java makes it so easy to change a single-tasking program into a multithreaded one.



JavaT 2 Developer Exam CramT 2 (Exam CX-310-252A and CX-310-027)
JavaT 2 Developer Exam CramT 2 (Exam CX-310-252A and CX-310-027)
ISBN: N/A
EAN: N/A
Year: 2003
Pages: 187

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net