代碼來自網上。
1.文件處理類 processer.java
1 package webbook.chapter2; 2 3 import java.io.*; 4 import java.net.Socket; 5 6 /** 7 * 處理一個HTTP用戶請求的線程類。 8 */ 9 public class Processor extends Thread { 10 private PrintStream out; 11 private InputStream input; 12 /** 默認的服務器存放訪問內容的目錄 */ 13 public static final String WEB_ROOT = "/library/webserver/documents"; 14 15 public Processor(Socket socket) { 16 try { 17 input = socket.getInputStream(); 18 out = new PrintStream(socket.getOutputStream()); 19 } catch (IOException e) { 20 e.printStackTrace(); 21 } 22 } 23 24 public void run() { 25 try { 26 String fileName = parse(input); 27 readFile(fileName); 28 } catch (IOException e) { 29 e.printStackTrace(); 30 } 31 } 32 33 /** 34 * 解析客戶機發過的所有HTTP請求,如果是符合HTTP協議內容的, 就分析出客戶機所要訪問文件的名字,並且返回文件名。 35 */ 36 public String parse(InputStream input) throws IOException { 37 BufferedReader in = new BufferedReader(new InputStreamReader(input)); 38 String inputContent = in.readLine(); 39 if (inputContent == null || inputContent.length() == 0) { 40 sendError(400, "Client invoke error"); 41 return null; 42 } 43 // 分析客戶請求的HTTP信息,分析出到底想訪問哪個文件, 44 // 發過來的HTTP請求應該是三部分。 45 46 String request[] = inputContent.split(" "); 47 if (request.length != 3) { 48 sendError(400, "Client invoke error"); 49 return null; 50 } 51 // 第一部分是請求的方法 52 String method = request[0]; 53 // 第二部分是請求的文件名 54 String fileName = request[1]; 55 // 第三部分是HTTP版本號 56 String httpVersion = request[2]; 57 System.out.println("Method: " + method + ", file name: " + fileName + ", HTTP version: " + httpVersion); 58 return fileName; 59 } 60 61 /** 62 * 處理調用一個文件的請求 63 */ 64 public void readFile(String fileName) throws IOException { 65 File file = new File(Processor.WEB_ROOT + fileName); 66 if (!file.exists()) { 67 sendError(404, "File Not Found"); 68 return; 69 } 70 // 把文件的內容讀取到in對象中。 71 InputStream in = new FileInputStream(file); 72 byte content[] = new byte[(int) file.length()]; 73 in.read(content); 74 out.println("HTTP/1.0 200 sendFile"); 75 out.println("Content-length: " + content.length); 76 out.println(); 77 out.write(content); 78 out.flush(); 79 out.close(); 80 in.close(); 81 } 82 83 /** 84 * 發送錯誤的信息 85 */ 86 public void sendError(int errNum, String errMsg) { 87 out.println("HTTP/1.0 " + errNum + " " + errMsg); 88 out.println("Content-type: text/html"); 89 out.println(); 90 out.println("<html>"); 91 out.println("<head><title>Error " + errNum + "--" + errMsg + "</title></head>"); 92 out.println("<h1>" + errNum + " " + errMsg + "</h1>"); 93 out.println("</html>"); 94 out.println(); 95 out.flush(); 96 out.close(); 97 } 98 }
2.webserver.java
1 package webbook.chapter2; 2 3 import java.io.IOException; 4 import java.net.ServerSocket; 5 import java.net.Socket; 6 7 public class WebServer { 8 /** 默認使用的服務器Socket端口號 */ 9 public static final int HTTP_PORT = 8080; 10 private ServerSocket serverSocket; 11 12 public void startServer(int port) { 13 try { 14 serverSocket = new ServerSocket(port); 15 System.out.println("Web Server startup on " + port); 16 while (true) { 17 Socket socket = serverSocket.accept(); 18 // 通過線程的方式來處理客戶的請求 19 new Processor(socket).start(); 20 } 21 } catch (IOException e) { 22 e.printStackTrace(); 23 } 24 } 25 26 /** 27 * WebServer類的啟動方法,可以通過命令行參數指定當前Web服務器所使用的端口號。 28 */ 29 public static void main(String[] argv) throws Exception { 30 WebServer server = new WebServer(); 31 if (argv.length == 1) { 32 server.startServer(Integer.parseInt(argv[0])); 33 } else { 34 server.startServer(WebServer.HTTP_PORT); 35 } 36 } 37 }
簡單webserver 充當的作用就是接受客戶端程序發過來的請求,根據請求內容轉換的數據找到自己制定路徑下的文件,將其文件轉為流返回客服端,這個過程所用的協議為http。
