Home : Course Map : Chapter 14 :
Running HTTP Server
JavaTech
Course Map
Chapter 14

Web Servers
Design of Server
ServerSocket
Threads For Clients
Client Streams
HTTP Protocol
Run Server
  Demo 1
Secure Server
  Demo 2
More Security
A client application
  Demo 3
Server Apps
Servlets
Exercises

     About JavaTech
     Codes List
     Exercises
     Feedback
     References
     Resources
     Tips
     Topic Index
     Course Guide
     What's New

In the directory with MicroServer.java we put a simple Web page file named message.html.

We run our server application from the command line as follows:

> java MicroServer 1234

The program can receive the port number as an argument (on a Unix platform you should pick a port number above 1023) or it will use the default of 2222. Here we see the program starting and the output that results when a page request arrives from a client:

From a browser on the same machine (using the 127.0.0.1 IP address for the local machine) we can request the message file. A browser screen capture shows:

Below we repeat the code listings again so that you can see the two classes together:

import java.net.*;
import java.io.*;
import java.util.*;

/**
  * An application to create a ServerSocket object and
  * spin off a threaded process to serve each client.
 **/
public class MicroServer {

  public static void main (String argv[]) throws IOException {

    int port; // port number

    // Get the port number from the command line.
    try{
      port = Integer.parseInt (argv[0]);
    } catch (Exception e) {
      port = 2222; // Default
      System.out.println ("Use default port = 2222");
    }

    // Create a ServerSocket object to watch that port for clients
    ServerSocket server_socket = new ServerSocket (port);
    System.out.println ("Server started");

    // Loop indefinitely while waiting for clients to connect
    while (true) {

      // accept () does not return until a client requests a connection
      Socket client_socket = server_socket.accept ();

      // Now that a client has arrived, create an instance of our special
      // thread subclass to respond to it.
      Worker worker = new Worker (client_socket);
      worker.start ();
      System.out.println ("New client connected");
    }
  } // main

} // class MicroServer
import java.net.*;
import java.io.*;
import java.util.*;

/** Threaded process to serve the client connected to the socket.**/
class Worker extends Thread {

  Socket fClient = null;

  /** Pass the socket as a argument to the constructor **/
  Worker ( Socket client ) throws SocketException {
    fClient = client;

    // Set the thread priority down so that the ServerSocket
    // will be responsive to new clients.
    setPriority ( NORM_PRIORITY - 1 );
  } // ctor

  /**
    *  This thread receives a message from the client that will
    *  request a web page file. The file name is found relative to
    *  the directory location of this code.
   **/
  public void run () {
    try {
      // Use the client socket to obtain an input stream from it.
      InputStream socket_in = fClient.getInputStream ();
      // For text input we wrap an InputStreamReader around
      // the raw input stream and set ASCII character encoding.
      InputStreamReader isr =
         new InputStreamReader (socket_in, "8859_1");
      // Finally, use a BufferReader wrapper to obtain
      // buffering and higher order read methods.
      BufferedReader client_in = new BufferedReader (isr);

      // Now get an output stream to the client.
      OutputStream client_out = fClient.getOutputStream ();

      // For text output we wrap an OutputStreamWriter around
      // the raw output stream and set ASCII character encoding.
      OutputStreamWriter osr =
        new OutputStreamWriter (client_out, "8859_1");
      // Finally, we use a PrintWriter wrapper to obtain its
      // higher level output methods.Open in autoflush mode.
      // (Autoflush occurs only with println() method.)
      PrintWriter pw_client_out = new PrintWriter (osr, true );

      // First read the message from the client
      String client_str = client_in.readLine ();
      System.out.println ("Client message: "+client_str);

      // Split the message into substrings.
      String [] tokens = client_str.split(" ");

      // Check that the message has a minimun number of words
      // and that the first word is the GET command.
      if ((tokens.length >= 2) &&
           tokens[0].equals ("GET")) {
         String file_name = tokens[1];

        // Ignore the leading "/" on the file name.
        if (file_name.startsWith ("/"))
            file_name = file_name.substring (1);

        // If no file name is there, use index.html default.
        if (file_name.endsWith ("/") || file_name.equals (""))
           file_name = file_name + "index.html";

        // Check if the file is hypertext or plain text
        String content_type;
        if (file_name.endsWith (".html") ||
            file_name.endsWith (".htm")) {
           content_type = "text/html";
        }
        else {
          content_type = "text/plain";
        }
        // Now read the file from the disk and write it to the
        // output stream to the client.
        try {

          // Open a stream to the file.
          FileInputStream file_in = new FileInputStream  (file_name);

          // Send the header.
          pw_client_out.print ("HTTP/1.0 200 OK\r\n");
          File file = new File (file_name);
          Date date = new Date (file.lastModified ());
          pw_client_out.print ("Date: " + date + "\r\n");
          pw_client_out.print ("Server: MicroServer 1.0\r\n");
          pw_client_out.print ("Content-length: " + file_in.available ()
            + "\r\n");
          pw_client_out.print ("Content-type: " + content_type
            + "\r\n\r\n");

          // Creat a byte array to hold the file.
          byte [] data = new byte [file_in.available ()];

          file_in.read (data);     // Read file into the byte array
          client_out.write (data); // Write it to client output stream
          client_out.flush ();     // Remember to flush output buffer
          file_in.close ();        // Close file input stream

        } catch (FileNotFoundException e) {
          // If no such file, then send the famous 404 message.
          pw_client_out.println ("404 Object Not Found" );
        }
      } else{
        pw_client_out.println ("400 Bad Request");
      }
    } catch (IOException e) {
      System.out.println ( "I/O error " + e );
    }

    // Close client socket.
    try {
      fClient.close ();
    } catch (IOException e){
      System.out.println ("I/O error " + e );
    }
    // On return from run () the thread process will stop.
  } // run

} // class Worker

 

References & Web Resources

Latest update: Dec. 15, 2004
  
  Part I Part II Part III
Java Core 1  2  3  4  5  6  7  8  9  10  11  12 13 14 15 16 17
18 19 20
21
22 23 24
Supplements

1  2  3  4  5  6  7  8  9  10  11  12

Tech 1  2  3  4  5  6  7  8  9  10  11  12
Physics 1  2  3  4  5  6  7  8  9  10  11  12

Java is a trademark of Sun Microsystems, Inc.