大家帮我看一下这个程序;简要解释一下 并修改一下 谢谢
1 /*
2 * An example of a very simple, 
  * multi-threaded HTTP server.
3 * Implementation notes are in 
  * WebServer.html, and also
4 * as comments in the source code.
5 */
6
7 import java.io.*;
8 import java.net.*;
9 import java.util.*;
10
11 class WebServer implements HttpConstants {
12
13  /* static class data/methods */
14
15  /* print to stdout */
16  protected static void p(String s) {
17       System.out.println(s);
18      }
19
20  /* print to the log file */ 
21  protected static void log(String s) {
22    synchronized (log) {
23        log.println(s);
24        log.flush();
25       }
26   }
27
28  static PrintStream log = null;
29 /* our server's configuration information 
    *                              is stored
30  * in these properties
31  */
32  protected static Properties props = 
                           new Properties();
33
34 /* Where worker threads stand idle */
35 static Vector threads = new Vector();
36
37 /* the web server's virtual root */
38 static File root;
39
40 /* timeout on client connections */
41 static int timeout = 0;
42
43 /* max # worker threads */
44 static int workers = 5;
45
46
47 /* load www-server.properties from java.home     
48  */    
49 static void loadProps() throws IOException 
                     {  File f = new File
    (System.getProperty(
             "java.home")+File.separator+
50  "lib"+File.separator+"www-server.properties");
51   if (f.exists()) {
52  InputStream is =new BufferedInputStream(new
53                     FileInputStream(f));
54    props.load(is);
55     is.close();
56  String r = props.getProperty("root");
57   if (r != null) {
58     root = new File(r);
59  if (!root.exists()) {
60  throw new Error(root + " doesn't exist as 
              server root");
61     }
62      }
63  r = props.getProperty("timeout");
64  if (r != null) {
65  timeout = Integer.parseInt(r);
66     }
67  r = props.getProperty("workers");
68  if (r != null) {
69   workers = Integer.parseInt(r);
70     }
71   r = props.getProperty("log");
72  if (r != null) {
73   p("opening log file: " + r);
74  log = new PrintStream(new BufferedOutputStream(
75          new FileOutputStream(r)));
76     }
77  }
78
79  /* if no properties were specified, 
     *  choose defaults */
80     if (root == null) {
81  root = new File(System.getProperty(
                           "user.dir"));
82   }
83  if (timeout <= 1000) {
84     timeout = 5000;
85    }
86   if (workers  25) {
87   workers = 5;
88   }
89   if (log == null) {
90   p("logging to stdout");
91        log = System.out;
92     }
93  }
94
95  static void printProps() {
96     p("root="+root);
97     p("timeout="+timeout);
98     p("workers="+workers);
99    }
100
101 public static void main(
         String[] a) throws Exception {
102          int port = 8080;
103          if (a.length > 0) {
104      port = Integer.parseInt(a[0]);
105          }
106     loadProps();
107     printProps();
108     /* start worker threads */
109   for (int i = 0; i < workers; ++i) {
110  Worker w = new Worker();
111   (new Thread(w, "worker #"+i)).start();
112   threads.addElement(w);
113          }
114
115  ServerSocket ss = new ServerSocket(port);
116    while (true) {
117
118   Socket s = ss.accept();
119
120  Worker w = null;  
     
121    synchronized (threads) {
122   if (threads.isEmpty()) {
123     Worker ws = new Worker();
124       ws.setSocket(s);
125      (new Thread(ws, "additional worker")).start();
126   } else {
127    w = (Worker) threads.elementAt(0);
128     threads.removeElementAt(0);
129       w.setSocket(s);
130       }
131    }
132  }
133      }
134  }
135
136    

解决方案 »

  1.   

    137  class Worker extends WebServer
         implements HttpConstants, Runnable {
    138   final static int BUF_SIZE = 2048;
    139
    140  static final byte[] EOL = 
                   {(byte)'\r', (byte)'\n' };
    141
    142  /* buffer to use for requests */
    143    byte[] buf;
    144  /* Socket to client we're handling */
    145  private Socket s;
    146
    147   Worker() {
    148     buf = new byte[2048];
    149    s = null;
    150      }
    151   
    152  synchronized void setSocket(Socket s) {
    153     this.s = s;
    154     notify();
    155      }
    156
    157   public synchronized void run() {
    158    while(true) {
    159      if (s == null) {
    160    /* nothing to do */
    161   try {        
              
    162    wait();
    163     } catch (InterruptedException e) {
    164    /* should not happen */
    165     continue;
    166     }
    167    }
    168   try {
    169     handleClient();
    170     } catch (Exception e) {
    171    e.printStackTrace();
    172    }
    173   /* go back in wait queue if there's fewer
    174    * than numHandler connections.
    175    */
    176     s = null;
    177   Vector pool = WebServer.threads;
    178   synchronized (pool) {
    179    if (pool.size() >= WebServer.workers) {
    180     /* too many threads, exit this one */
    181    return;
    182    } else {
    183   pool.addElement(this);
    184       }
    185      }
    186    }
    187 }
    188   
    189  void handleClient() throws IOException {
    190  InputStream is = new BufferedInputStream(
                      s.getInputStream());
    191 PrintStream ps = new PrintStream(
                       s.getOutputStream());
    192  /* we will only block in read 
          *          for this many milliseconds
    193   * before we fail with 
          *     java.io.InterruptedIOException,
    194   * at which point we will 
          * abandon the connection.
    195  */
    196   s.setSoTimeout(WebServer.timeout);
    197
    198 /* zero out the buffer from last time */
    199  for (int i = 0; i
    200     buf[i] = 0;
    201
    202   try {
    203  /* We only support HTTP GET/HEAD, and don't
    204  * support any fancy HTTP options,
    205  * so we're only interested really in
    206   * the first line.
    207               */
    208   int nread = 0, r = 0;
    209
    210  outerloop:
    211    while (nread < BUF_SIZE) {
    212    r = is.read(buf, nread, BUF_SIZE - nread);
    213   if (r == -1) {
    214      /* EOF */
    215       return;
    216    }
    217   int i = nread;
    218    nread += r;
    219    for (; i < nread; i++) {
    220    if (buf[i] == (byte)'\n' || 
                       buf[i] == (byte)'\r') {
    221      break outerloop;
    222       }
    223       }
    224       }
    225
    226  /* are we doing a GET or just a HEAD */
    227    boolean doingGet;
    228    /* beginning of file name */
    229    int index;
    230   if (buf[0] == (byte)'G' &&
    231     buf[1] == (byte)'E' &&
    232  
    233    buf[2] == (byte)'T' &&
    234  
    235    buf[3] == (byte)' ') {
    236    doingGet = true;
    237     index = 4;
    238     } else if (buf[0] == (byte)'H' &&
    239      buf[1] == (byte)'E' &&
    240  
    241  buf[2] == (byte)'A' &&
    242  
    243  buf[3] == (byte)'D'&&
    244  
    245   buf[4] == (byte)' ') {
    246    doingGet = false;
    247   index = 5; 
    248    } else {
    249   /* we don't support this method */
    250  ps.print("HTTP/1.0 " + HTTP_BAD_METHOD +
    251   " unsupported method type: ");
    252   ps.write(buf, 0, 5);
    253  ps.write(EOL);
    254    ps.flush();
    255    s.close();
    256    return;
    257     }
    258
    259 int i = 0;
    260  for (i = index; i < nread; i++) {
    261  if (buf[i] == (byte)' ') {
    262    break;
    263      }
    264     }
    265  String fname = (new String(buf, 0, index,
            i-index)).replace('/', File.separatorChar);
    266   if (fname.startsWith(File.separator)) {
    267    fname = fname.substring(1);
    268    }
    269  File targ = new File(WebServer.root, fname);
    270   if (targ.isDirectory()) {
    271    File ind = new File(targ, "index.html");
    272   if (ind.exists()) {
    273     targ = ind;
    274     }
    275      }
    276    boolean OK = printHeaders(targ, ps);
    277    if (doingGet) {
    278   if (OK) {       
              
    279   sendFile(targ, ps);
    280   } else {
    281     send404(targ, ps);
    282        }
    283    }
    284    } finally {
    285      s.close();
    286          }
    287      } 
    288
    289   boolean printHeaders(File targ, 
           PrintStream ps) throws IOException {
    290      boolean ret = false;
    291   int rCode = 0;
    292    if (!targ.exists()) {
    293    rCode = HTTP_NOT_FOUND;
    294    ps.print("HTTP/1.0 " + HTTP_NOT_FOUND + " not found");
    295    ps.write(EOL);
    296   ret = false;
    297    }  else {
    298    rCode = HTTP_OK;
    299   ps.print("HTTP/1.0 " + HTTP_OK+" OK");
    300   ps.write(EOL);
    301   ret = true;
    302    }      
    303  log("From " +s.getInetAddress().getHostAddress()+
    304    ": GET " +targ.getAbsolutePath()+"-->"+rCode);
    305   ps.print("Server: Simple java");
    306    ps.write(EOL);
    307    ps.print("Date: " + (new Date()));
    308   ps.write(EOL);
    309   if (ret) {
    310    if (!targ.isDirectory()) {
    311      ps.print("Content-length: "+targ.length());
    312      ps.write(EOL);
    313     ps.print("Last Modified: " + (new
             Date(targ.lastModified())));
    314    ps.write(EOL);
    315    String name = targ.getName();
    316      int ind = name.lastIndexOf('.');
    317   String ct = null;
    318     if (ind > 0) {
    319     ct = (String) map.get(name.substring(ind));
    320    }
    321    if (ct == null) {
    322      ct = "unknown/unknown";
    323      }
    324     ps.print("Content-type: " + ct);
    325     ps.write(EOL);
    326    } else {
    327      ps.print("Content-type: text/html");
    328    ps.write(EOL);
    329       }
    330          }
    331          return ret;
    332      }
    333
    334   void send404(File targ, PrintStream ps)
                          throws IOException {
    335    ps.write(EOL);
    336    ps.write(EOL);
    337    ps.println("Not Found\n\n"+
    338    "The requested resource was not found.\n");
    339      }
    340
      

  2.   

    341 void sendFile(File targ, PrintStream ps)
                 throws IOException {
    342   InputStream is = null;
    343   ps.write(EOL);
    344    if (targ.isDirectory()) {
    345    /* here, we take advantage of the fact
    346    * that FileURLConnection will parse a directory
    347    * listing into HTML for us.
    348    */
    349   File ind = new File(targ, "index.html");
    350   if (ind.exists()) {
    351     is = new FileInputStream(ind);
    352      } else {
    353     URL u = new URL("file", "", targ.getAbsolutePath());
    354    is = u.openStream();
    355     }
    356    } else {
    357    is = new FileInputStream(targ.getAbsolutePath());
    358      }
    359    
    360   try {
    361    int n;
    362    while ((n = is.read(buf)) > 0) {
    363    ps.write(buf, 0, n);
    364      }
    365     } finally {
    366       is.close();
    367          }
    368      }
    369
    370  /* mapping of file extensions to 
          *content-types */
    371  static java.util.Hashtable map = 
          new java.util.Hashtable();
    372
    373    static {
    374          fillMap();
    375    }
    376  static void setSuffix(String k, String v) {
    377          map.put(k, v);
    378      }
    379
    380  static void fillMap() {
    381  setSuffix("", "content/unknown");
    382  setSuffix(".uu", "application/octet-stream");
    383  setSuffix(".exe", "application/octet-stream");
    384  setSuffix(".ps", "application/postscript");
    385  setSuffix(".zip", "application/zip");
    386  setSuffix(".sh", "application/x-shar");
    387  setSuffix(".tar", "application/x-tar");
    388  setSuffix(".snd", "audio/basic");
    389  setSuffix(".au", "audio/basic");
    390  setSuffix(".wav", "audio/x-wav");
    391  setSuffix(".gif", "image/gif");
    392  setSuffix(".jpg", "image/jpeg");
    393  setSuffix(".jpeg", "image/jpeg");
    394  setSuffix(".htm", "text/html");
    395  setSuffix(".html", "text/html");
    396  setSuffix(".text", "text/plain");
    397  setSuffix(".c", "text/plain");
    398  setSuffix(".cc", "text/plain");
    399  setSuffix(".c++", "text/plain");
    400  setSuffix(".h", "text/plain");
    401  setSuffix(".pl", "text/plain");
    402  setSuffix(".txt", "text/plain");
    403  setSuffix(".java", "text/plain");
    404      }
    405
    406  }
    407
    408  interface HttpConstants {
    409  /** 2XX: generally "OK" */
    410  public static final int HTTP_OK = 200;
    411  public static final int HTTP_CREATED = 201;
    412  public static final int HTTP_ACCEPTED = 202;
    413  public static final int HTTP_NOT_AUTHORITATIVE = 203;
    414  public static final int HTTP_NO_CONTENT = 204;
    415  public static final int HTTP_RESET = 205;
    416  public static final int HTTP_PARTIAL = 206;
    417
    418  /** 3XX: relocation/redirect */
    419  public static final int HTTP_MULT_CHOICE = 300;
    420  public static final int HTTP_MOVED_PERM = 301;
    421  public static final int HTTP_MOVED_TEMP = 302;
    422  public static final int HTTP_SEE_OTHER = 303;
    423  public static final int HTTP_NOT_MODIFIED = 304;
    424  public static final int HTTP_USE_PROXY = 305;
    425
    426 /** 4XX: client error */
    427  public static final int HTTP_BAD_REQUEST = 400;
    428  public static final int HTTP_UNAUTHORIZED = 401;
    429  public static final int HTTP_PAYMENT_REQUIRED = 402;
    430  public static final int HTTP_FORBIDDEN = 403;
    431  public static final int HTTP_NOT_FOUND = 404;
    432  public static final int HTTP_BAD_METHOD = 405;
    433  public static final int HTTP_NOT_ACCEPTABLE = 406;
    434  public static final int HTTP_PROXY_AUTH = 407;
    435  public static final int HTTP_CLIENT_TIMEOUT = 408;
    436  public static final int HTTP_CONFLICT = 409;
    437  public static final int HTTP_GONE = 410;
    438  public static final int HTTP_LENGTH_REQUIRED = 411;
    439  public static final int HTTP_PRECON_FAILED = 412;
    440  public static final int HTTP_ENTITY_TOO_LARGE = 413;
    441  public static final int HTTP_REQ_TOO_LONG = 414;
    442  public static final int HTTP_UNSUPPORTED_TYPE = 415;
    443
    444  /** 5XX: server error */
    445  public static final int HTTP_SERVER_ERROR = 500;
    446  public static final int HTTP_INTERNAL_ERROR = 501;
    447  public static final int HTTP_BAD_GATEWAY = 502;
    448  public static final int HTTP_UNAVAILABLE = 503;
    449  public static final int HTTP_GATEWAY_TIMEOUT = 504;
    450  public static final int HTTP_VERSION = 505;
    451  }