- Everything You Need To Know about TCP/IP but Failed to Learn in Kindergarten
- A Client Socket in Java
- Sending Email by Java
- A Server Socket in Java
- HTTP and Web Browsing: Retrieving HTTP Pages
- How to Make an Applet Write a File on the Server
- A Multithreaded HTTP Server
- A Mapped I/O HTTP Server
- Further Reading
- Exercises
- Some Light Relief—Using Java to Stuff an Online Poll
A Multithreaded HTTP Server
There's one improvement that is customary in servers, and we will make it here. For all but the smallest of servers, it is usual to spawn a new thread to handle each request. This has three big advantages:
Foremost, it makes the server scalable. The server can accept new requests independent of its speed in handling them. (Of course, you better buy a server that has the mippage to keep up with requests.)
By handling each request in a new thread, clients do not have to wait for every request ahead of them to be served.
The program source can be better organized, as the server processing is written in a different class.
The following code demonstrates how we would modify our HTTP web server to a new thread for each client request. The first step is to make another child in the One_Connection hierarchy to implement the Runnable interface. Give it a run method that will actually do all the work: get the request, then send the file.
import java.io.*; import java.net.*; class OneConnection_C extends OneConnection_B implements Runnable { OneConnection_C(Socket sock) throws Exception { super(sock); } public void run() { try { String filename = getRequest(); sendFile(filename); } catch (Exception e) { System.out.println("Excpn: " + e);} } }
The main program will have the server socket and it will put the accept in a loop (so that we can handle many requests, not just the first one). It will instantiate our connection class as before, turn it into a thread, and invoke its start method. The code follows:
public class HTTPServer4 { public static void main(String a[]) throws Exception { final int httpd = 80; ServerSocket ssock = new ServerSocket(httpd); while (true) { Socket sock = ssock.accept(); System.out.println("client has made socket connection"); OneConnection_C client = new OneConnection_C(sock); new Thread(client).start(); } } }
The code seems so brief because we have draped the functionality across several classes in an inheritance hierarchy. That was done so that the example code would be smaller and easier to present. You should try putting the code back into one or two classes. It's still only 50 or 60 lines long. This has got to be the world record for the smallest HTTP server.