JAVA100例]050、一个简单的Web服务器(java100例)import java.io.*;import java.net.*;/** * <p>Title: 发现HTTP内容和文件内容</p> * <p>Description: 获得用户请求后将用户需要的文件读出,添加上HTTP应答头。发送给客户端。</p> * <p>Copyright: Copyright (c) 2003</p> * <p>Filename: Response.java</p> * @version 1.0 */public class Response{ OutputStream out = null;/** *<br>方法说明:发送信息 *<br>输入参数:String ref 请求的文件名 *<br>返回类型: */ public void Send(String ref) throws IOException { byte[] bytes = new byte[2048]; FileInputStream fis = null; try { //构造文件 File file = new File(WebServer.WEBROOT, ref); if (file.exists()) { //构造输入文件流 fis = new FileInputStream(file); int ch = fis.read(bytes, 0, 2048); //读取文件 String sBody = new String(bytes,0); //构造输出信息 String sendMessage = "HTTP/1.1 200 OK/r/n" + "Content-Type: text/html/r/n" + "Content-Length: "+ch+"/r/n" + "/r/n" +sBody; //输出文件 out.write(sendMessage.getBytes()); }else { // 找不到文件 String errorMessage = "HTTP/1.1 404 File Not Found/r/n" + "Content-Type: text/html/r/n" + "Content-Length: 23/r/n" + "/r/n" + "<h1>File Not Found</h1>"; out.write(errorMessage.getBytes()); } } catch (Exception e) { // 如不能实例化File对象,抛出异常。 System.out.println(e.toString() ); } finally { if (fis != null) fis.close(); } }/** *<br>方法说明:构造器,获取输出流 *<br>输入参数: *<br>返回类型: */ public Response(OutputStream output) { this.out = output;}} import java.io.*;import java.net.*;/** * <p>Title: 客户请求分析</p> * <p>Description: 获取客户的HTTP请求,分析客户所需要的文件</p> * <p>Copyright: Copyright (c) 2003</p> * <p>Filename: Request.java</p> * @version 1.0 */public class Request{ InputStream in = null;/** *<br>方法说明:构造器,获得输入流。这时客户的请求数据。 *<br>输入参数: *<br>返回类型: */ public Request(InputStream input){ this.in = input; }/** *<br>方法说明:解析客户的请求 *<br>输入参数: *<br>返回类型:String 请求文件字符 */ public String parse() { //从Socket读取一组数据 StringBuffer requestStr = new StringBuffer(2048); int i; byte[] buffer = new byte[2048]; try { i = in.read(buffer); } catch (IOException e) { e.printStackTrace(); i = -1; } for (int j=0; j<i; j++) { requestStr.append((char) buffer[j]); } System.out.print(requestStr.toString()); return getUri(requestStr.toString()); }/** *<br>方法说明:获取URI字符 *<br>输入参数:String requestString 请求字符 *<br>返回类型:String URI信息字符 */ private String getUri(String requestString) { int index1, index2; index1 = requestString.indexOf(' '); if (index1 != -1) { index2 = requestString.indexOf(' ', index1 + 1); if (index2 > index1) return requestString.substring(index1 + 1, index2); } return null; }} import java.io.*;import java.net.*;import java.util.*;/** * <p>Title: WEB服务器</p> * <p>Description: 使用Socket创建一个WEB服务器,本程序是多线程系统以提高反应速度。</p> * <p>Copyright: Copyright (c) 2003</p> * <p>Filename: WebServer.java</p> * @version 1.0 */class WebServer{ public static String WEBROOT = "";//默认目录 public static String defaultPage = "index.htm";//默认文件 public static void main (String [] args) throws IOException {//使用输入的方式通知服务默认目录位置,可用./root表示。 if(args.length!=1){ System.out.println("USE: java WebServer ./rootdir"); return; }else{ WEBROOT = args[0]; } System.out.println ("Server starting.../n"); //使用8000端口提供服务 ServerSocket server = new ServerSocket (8000); while (true) { //阻塞,直到有客户连接 Socket sk = server.accept (); System.out.println ("Accepting Connection.../n"); //启动服务线程 new WebThread (sk).start (); } }}/** * <p>Title: 服务子线程</p> * <p>Description: 使用线程,为多个客户端服务</p> * <p>Copyright: Copyright (c) 2003</p> * <p>Filename: </p> * @author 杜江 * @version 1.0 */class WebThread extends Thread{ private Socket sk; WebThread (Socket sk) { this.sk = sk; }/** *<br>方法说明:线程体 *<br>输入参数: *<br>返回类型: */ public void run () { InputStream in = null; OutputStream out = null; try{ in = sk.getInputStream(); out = sk.getOutputStream(); //接收来自客户端的请求。 Request rq = new Request(in); //解析客户请求 String sURL = rq.parse(); System.out.println("sURL="+sURL); if(sURL.equals("/")) sURL = WebServer.defaultPage; Response rp = new Response(out); rp.Send(sURL); }catch (IOException e) { System.out.println (e.toString ()); } finally { System.out.println ("Closing Connection.../n"); //最后释放资源 try{ if (in != null) in.close (); if (out != null) out.close (); if (sk != null) sk.close (); } catch (IOException e) { } } }}