大家帮我看一下这个程序;简要解释一下 并修改一下 谢谢
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 /*
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
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
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 }