Corrections to Chapter 8 of Java Network Programming, Sockets for Servers

p. 188: In the code fragemnt in the middle of the page, InetAddress.getHostByName("sunsite.unc.edu") should be InetAddress.getByName("sunsite.unc.edu"). That is,

try {
  ServerSocket httpd = new ServerSocket(5776, 100, 
   InetAddress.getByName("sunsite.unc.edu"));
}
catch (IOException e) {
  System.err.println(e);
}

p. 193: The setSoTimeout() method throws InterruptedIOException, not InterruptedException.

pp. 199: Example 8-5, onefile.java, has two problems. First, the thisLine variable should be initialized to the empty string "". Otherwise, "null" will be prefixed to the data. Secondly, I neglected to set the ContentLength field. There are many ways to fix this. One is to simply eliminate it completely as in the following:

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

public class onefile extends Thread {

  static String theData = "";
  static String ContentType;
  Socket theConnection;

  public static void main(String[] args) {

    int thePort;
    ServerSocket ss;
    Socket theConnection;
    FileInputStream theFile;

    // cache the file
    try {
      theFile = new FileInputStream(args[0]);
      DataInputStream dis = new DataInputStream(theFile);
      if (args[0].endsWith(".html") || args[0].endsWith(".htm")) {
        ContentType = "text/html";
      }
      else {
        ContentType = "text/plain";
      }
      
      try {
        String thisLine = "";
        while ((thisLine = dis.readLine()) != null) { 
          theData += thisLine + "\n";
        }
      }
      catch (Exception e) {
        System.err.println("Error: " + e);
      }

    }
    catch (Exception e) {
      System.err.println(e);
      System.err.println("Usage: java onefile filename port");
      System.exit(1);
    }
        
    // set the port to listen on
    try {
      thePort = Integer.parseInt(args[1]);
      if (thePort < 0 || thePort > 65535) thePort = 80;
    }  
    catch (Exception e) {
      thePort = 80;
    }  
                
    try {
      ss = new ServerSocket(thePort);
      System.out.println("Accepting connections on port " 
        + ss.getLocalPort());
      System.out.println("Data to be sent:");
      System.out.println(theData);
      while (true) {
        onefile fs = new onefile(ss.accept());
        fs.start();
      }
    }
    catch (IOException e) {
    
    }
  
  }
  
  public onefile(Socket s) {
    theConnection = s;
  }

  public void run() {
  
    try {
      PrintStream os = new PrintStream(theConnection.getOutputStream());
      DataInputStream is = new DataInputStream(theConnection.getInputStream());
      String request = is.readLine();
      // If this is HTTP/1.0 or later send a MIME header
      if (request.indexOf("HTTP/") != -1) {
        while (true) {  // read the rest of the MIME header
          String thisLine = is.readLine();
          if (thisLine.trim().equals("")) break; 
        }
        
        os.print("HTTP/1.0 200 OK\r\n");
        Date now = new Date();
        os.print("Date: " + now + "\r\n");
        os.print("Server: OneFile 1.0\r\n");
        os.print("Content-length: " + theData.length() + "\r\n");
        os.print("Content-type: " + ContentType + "\r\n\r\n");
      } // end if
      os.println(theData);
      theConnection.close();
    }  // end try
    catch (IOException e) {
    
    }

  }

}
Furthermore, the String field theData should be initialized to the empty string.

p. 209: The run() method in Example 8-7 (jhttp) checks if the method is GET and, if so, it parses the header to get the protocol version. On p 210, if the method is not GET, it checks the protocol version without ever having parsed the header to find the protocol version, so it will never execute the code to generate the 'Not implemented' response. This is a bug, though it won't crash the program. The following revised run() method fixes the problem.

  public void run() {
  
    String method;
    String file="";
    String ct;
    String version = "";
    File theFile;
  
    try {
      PrintStream os = new PrintStream(theConnection.getOutputStream());
      DataInputStream is = new DataInputStream(theConnection.getInputStream());
      String get = is.readLine();
      StringTokenizer st = new StringTokenizer(get);
      method = st.nextToken();
      if (st.hasMoreTokens()) {
        file = st.nextToken();
        if (file.endsWith("/")) file += indexfile;
      }
      if (st.hasMoreTokens()) version = st.nextToken();
      if (method.equals("GET")) {                
        ct = guessContentTypeFromName(file);
        // loop through the rest of the input lines         
        while ((get = is.readLine()) != null) {
          if (get.trim().equals("")) break;        
        }

        try {
          theFile = new File(docroot, file.substring(1,file.length()));
          FileInputStream fis = new FileInputStream(theFile);
          byte[] theData = new byte[(int) theFile.length()];
          // need to check the number of bytes read here
          fis.read(theData);
          fis.close();

          if (version.startsWith("HTTP/")) {  // send a MIME header
            os.print("HTTP/1.0 200 OK\r\n");
            Date now = new Date();
            os.print("Date: " + now + "\r\n");
            os.print("Server: jhttp 1.0\r\n");
            os.print("Content-length: " + theData.length + "\r\n");
            os.print("Content-type: " + ct + "\r\n\r\n");
          }  // end try
          
          // send the file
          os.write(theData);
          os.close();
        }  // end try
        catch (IOException e) {  // can't find the file
          if (version.startsWith("HTTP/")) {  // send a MIME header
            os.print("HTTP/1.0 404 File Not Found\r\n");
            Date now = new Date();
            os.print("Date: " + now + "\r\n");
            os.print("Server: jhttp 1.0\r\n");
            os.print("Content-type: text/html" + "\r\n\r\n");
          } 
          os.println("<HTML><HEAD><TITLE>File Not Found</TITLE></HEAD>");
          os.println("<BODY><H1>HTTP Error 404: File Not Found</H1></BODY></HTML>");
          os.close();
        }
      }
      else {  // method does not equal "GET"
        if (version.startsWith("HTTP/")) {  // send a MIME header
          os.print("HTTP/1.0 501 Not Implemented\r\n");
          Date now = new Date();
          os.print("Date: " + now + "\r\n");
          os.print("Server: jhttp 1.0\r\n");
          os.print("Content-type: text/html" + "\r\n\r\n"); 
        }       
        os.println("<HTML><HEAD><TITLE>Not Implemented</TITLE></HEAD>");
        os.println("<BODY><H1>HTTP Error 501: Not Implemented</H1></BODY></HTML>");
        os.close();
      }
    }
    catch (IOException e) {
    
    }
    try {
      theConnection.close();
    }
    catch (IOException e) {
    }

  }

[ Java Network Programming Corrections | Java Network Programming Home Page | Table of Contents | Examples | Order from Amazon ] ]

Copyright 1998, 1999 Elliotte Rusty Harold
elharo@metalab.unc.edu
Last Modified September 16, 1999