tomcat(1)一个简单的web server
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                tomcat(1)一个简单的web server
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                【0】README
0.1)本文部分描述轉自“深入剖析tomcat”, 旨在學習 ?一個簡單的web server ?的基礎知識;
0.2)for complete source code, please visit?https://github.com/pacosonTang/HowTomcatWorks/tree/master/chapter1
 
【1】HTTP
【1.1】HTTP請求 1)一個HTTP請求包括以下3部分(parts):(干貨——一個HTTP請求包括以下3部分(parts)) p1)請求方法——統一資源標識符(URI)——協議/版本; p2)請求頭; p3)實體; 2)HTTP 請求的示例如下所示:(干貨——HTTP請求代碼荔枝) Post /examples/default.jsp HTTP/1.1 Accept: text/plain; text/html Accept-Language: en-gb Connection: Keep-Alive Host: localhost User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98) Content-Length: 33 Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate // 這里是空行(CRLF) lastName=Yun&firstName=Lin 對以上HTTP請求的分析(Analysis):(干貨——對HTTP請求的分析) A1)第一行:請求方法——URI——協議/版本(Post /examples/default.jsp HTTP/1.1) A2)HTTP1.1 支持的請求方法有:GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE; A3)URI:指定internet 資源的完整路徑;而統一資源定位符(URL) 是 URI 的一種類型; A4)在請求頭和請求實體間有一個空行:該空行只有 CRLF 符;CRLF 告訴HTTP 服務器請求實體正文從哪里開始;正文(lastName=Yun&firstName=Lin)【1.2】HTTP響應 1)HTTP響應也包括3部分(parts): part1)協議——狀態碼——描述; part2)響應頭; part3)響應實體段; 2)HTTP響應的荔枝,如下所示: HTTP/1.1 200 OK Server: Microsoft-IIS/4.0 Date: Mon, 5 Jan 2004 13:13:33 GMT Content-Type: text/html Last-Modified: Mon, 5 Jan 2004 13:13:12 GMT Content-Length: 112 //空行(CRLF) <html> <head> <title>hello, world</title> </head> <body> hello, world </body> </html> 對上述HTTP響應代碼的分析(Analysis): A1)第一行的200,表示狀態碼(請求發送成功); A2)響應頭和響應實體正文間由只包含 CRLF 的一個空行分隔; 【1.3】Socket類 1)看個荔枝:(創建一個套接字,用于與本地HTTP Server 進行通信(127.0.0.1 表示一個本地主機),發送HTTP請求接收server 的響應信息); // 創建一個套接字,用于與本地HTTP Server 進行通信(127.0.0.1 表示一個本地主機),發送HTTP請求接收server 的響應信息 // 采用tomcat 開啟8080 端口 public class SocketTest {public static void main(String[] args) throws Exception {try(Socket socket = new Socket("127.0.0.1", 8080)){OutputStream os = socket.getOutputStream();boolean autoflush = true;PrintWriter out = new PrintWriter(socket.getOutputStream(), autoflush);BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));// send an HTTP request to the web serverout.println("GET /index.jsp HTTP/1.1");out.println("Host: localhost:8080");out.println("Connection: Close");out.println();// read the responseboolean loop = true;StringBuffer sb = new StringBuffer(8096);while(loop) {if(in.ready()) {int i = 0;while(i != -1) {i = in.read();sb.append((char)i);}loop = false;}Thread.currentThread().sleep(50);}// display the response to the out consoleSystem.out.println(sb.toString());socket.close();}} }
【3】應用程序 0)intro:web服務器應用程序包括3個類: HttpServer, Request, Response; 1)我們先看運行結果(顯然發出了兩個HTTP 請求,瀏覽器發出一個獲取靜態資源的 HTTP請求, 而該靜態資源又 發出獲取圖像資源的 HTTP 請求)(干貨——顯然發出了兩個HTTP 請求): E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src>java com.tomcat.chapter1.HttpServer E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src GET /index.html HTTP/1.1 Host: localhost:8080 Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: zh-CN,zh;q=0.8,en;q=0.6GET /images/psu.jpg HTTP/1.1 Host: localhost:8080 Connection: keep-alive Accept: image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Referer: http://localhost:8080/index.html Accept-Encoding: gzip, deflate, sdch Accept-Language: zh-CN,zh;q=0.8,en;q=0.6GET /SHUTDOWN HTTP/1.1 Host: localhost:8080 Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
2)HttpServer, Request, Response 的源碼如下所示: public class HttpServer { // 接受HTTP 請求的web server/** WEB_ROOT is the directory where our HTML and other files reside.* For this package, WEB_ROOT is the "webroot" directory under the working* directory.* The working directory is the location in the file system* from where the java command was invoked.*/public static final String WEB_ROOT =System.getProperty("user.dir") + File.separator + "webroot";// shutdown commandprivate static final String SHUTDOWN_COMMAND = "/SHUTDOWN";// the shutdown command receivedprivate boolean shutdown = false;public static void main(String[] args) {System.out.println(System.getProperty("user.dir"));HttpServer server = new HttpServer();server.await();// 會在指定端口上等待HTTP請求。}public void await() {ServerSocket serverSocket = null;int port = 8080;try {serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));}catch (IOException e) {e.printStackTrace();System.exit(1);}// Loop waiting for a requestwhile (!shutdown) {Socket socket = null;InputStream input = null;OutputStream output = null;try {socket = serverSocket.accept();input = socket.getInputStream();output = socket.getOutputStream();// create Request object and parse,創建 HTTP請求對象Request request = new Request(input);request.parse(); // 解析HTTP請求字符串// create Response object,創建HTTP 響應對象Response response = new Response(output);response.setRequest(request);response.sendStaticResource(); // 發送靜態資源到client// Close the socketsocket.close();//check if the previous URI is a shutdown commandshutdown = request.getUri().equals(SHUTDOWN_COMMAND);}catch (Exception e) {e.printStackTrace();continue;}}} }public class Request { // 封裝 HTTP 請求字符串的類private InputStream input;private String uri;public Request(InputStream input) {this.input = input;}public void parse() {// Read a set of characters from the socketStringBuffer request = new StringBuffer(2048);int i;byte[] buffer = new byte[2048];try {i = input.read(buffer);}catch (IOException e) {e.printStackTrace();i = -1;}for (int j=0; j<i; j++) {request.append((char) buffer[j]);}System.out.print(request.toString());uri = parseUri(request.toString());}private String parseUri(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;}public String getUri() {return uri;}}public class Response { <span style="font-family: 宋體;">// 封裝 HTTP 響應字符串的類</span>private static final int BUFFER_SIZE = 1024;Request request;OutputStream output;public Response(OutputStream output) {this.output = output;}public void setRequest(Request request) {this.request = request;}public void sendStaticResource() throws IOException {byte[] bytes = new byte[BUFFER_SIZE];FileInputStream fis = null;try {File file = new File(HttpServer.WEB_ROOT, request.getUri());if (file.exists()) {fis = new FileInputStream(file);int ch = fis.read(bytes, 0, BUFFER_SIZE);while (ch!=-1) {output.write(bytes, 0, ch);ch = fis.read(bytes, 0, BUFFER_SIZE);}}else {// file not foundString 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>";output.write(errorMessage.getBytes());}}catch (Exception e) {// thrown if cannot instantiate a File objectSystem.out.println(e.toString() );}finally {if (fis!=null)fis.close();}} } 補充)本文總結了一張上述應用程序的調用流程圖
對上圖的分析(Analysis): A1)HttpServer: step1)創建服務器套接字,等待接收 client 發出HTTP 連接請求; step2)連接成功后,利用套接字創建輸入輸出流; step3)創建Request對象, 向Request構造函數傳入輸入流,并利用request實例對象解析 ?HTTP ?請求; step4)創建Response對象,向Response構造函數傳入輸出流,且設置 Response中的request變量引用,調用response對象的sendStaticResource方法發送靜態資源到 client;
A2)Request:HTTP請求對象,其parse方法用于讀取HTTP請求頭;其parseUri方法用于解析client 請求的 uri; A3)Response:HTTP響應對象,其sendStaticResource方法 讀取request解析出的uri對應的資源文件,并發送該文件數據到client端;
3)靜態資源html <html> <head> <title>How Tomcat Works</title> </head> <body> <img src="./images/psu.jpg"> <br> hello, my name is xiao tangtang. </body> </html>
4)最后po 出 整體的文件目錄架構
總結
以上是生活随笔為你收集整理的tomcat(1)一个简单的web server的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 官网验证怎么操作(怎么官方验证)
- 下一篇: ip反查怎么回事(ip反查是什么)
