第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁 慕課教程 HTTP 入門教程 HTTP 入門教程 手寫 WEB 服務(wù)器和 HTTP 協(xié)議

手寫 WEB 服務(wù)器和 HTTP 協(xié)議

本節(jié)我們將借助 Socket 實(shí)現(xiàn)服務(wù)的端口監(jiān)聽并根據(jù) Http 協(xié)議的請求和響應(yīng)結(jié)構(gòu),實(shí)現(xiàn)一個(gè)簡單的 Web 服務(wù)器,加深體驗(yàn) Web 服務(wù)和 Http 協(xié)議的原理。

1. Http服務(wù)基本要素

1.1 監(jiān)聽連接

瀏覽器每發(fā)起一次請求都需要跟服務(wù)端建立連接,服務(wù)端要時(shí)刻監(jiān)聽有沒有客戶端連接。傳輸層協(xié)議有 TCP/UDP 兩種,實(shí)現(xiàn)起來并沒有強(qiáng)制說用哪一種,下面是官方文檔對 Http 連接的說明:

HTTP communication usually takes place over TCP/IP connections. The default port is TCP 80 .

文檔中指明了連接通常用的是 TCP, TCP 不用考慮數(shù)據(jù)包亂序,丟失這些問題,實(shí)現(xiàn)起來更簡單,高效。在代碼層我們可以用 Socket 來實(shí)現(xiàn)我們的 TCP 傳輸服務(wù)。

1.2 接收數(shù)據(jù)

Socket 監(jiān)聽連接,在沒有連接到來之前一直是阻塞在 serverSocket.accept(); 有請求過來就可以運(yùn)行到下面的代碼,然后可以根據(jù)我們的輸入流讀取信息,根據(jù) Http 協(xié)議拆開獲取我們要的請求數(shù)據(jù)。

1.3 返回?cái)?shù)據(jù)

根據(jù)業(yè)務(wù)處理完獲得返回實(shí)體數(shù)據(jù),然后遵從 Http 協(xié)議格式構(gòu)造返回的消息報(bào)文。瀏覽器獲得到的數(shù)據(jù)也會根據(jù) Http 協(xié)議進(jìn)行渲染。

2. Http報(bào)文格式

Http 協(xié)議請求報(bào)文的本質(zhì)就是一堆字符串,只是這堆字符是有格式的,發(fā)送方跟接收方都需要按照這個(gè)格式來拼接和拆解內(nèi)容。我們要實(shí)現(xiàn)一個(gè) Web 服務(wù),了解這個(gè)是最基本的要素。

以下截圖的報(bào)文是通過 tcpflow(一款功能強(qiáng)大的、基于命令行的免費(fèi)開源工具)在 Linux 系統(tǒng)抓包獲取的。

sudo tcpflow -c port 8080

2.1 Request

http-request

request

圖中各種請求首部字段的具體含義/用途,會在下面章節(jié)中詳細(xì)講解到。

2.2 Response

一般情況下,服務(wù)器收到客戶端的請求后,就會有一個(gè) Http 的響應(yīng)消息,Http 響應(yīng)也由 4 部分組成,分別是:狀態(tài)行、響應(yīng)頭、空行 和 響應(yīng)實(shí)體。
response

圖中的首部字段和返回內(nèi)容(響應(yīng)實(shí)體)中間是有一個(gè)空行的。

3. 實(shí)現(xiàn)

3.1 效果

demo

  • Web 服務(wù)端監(jiān)聽 8090 端口;
  • 本地瀏覽器訪問 8090 頁面顯示 hello tomcat

3.2 代碼

package com.imooc.mytomcat.tomcat;

import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Mytomcat
 *
 * @author zhourj
 * description
 */
public class Mytomcat {
    public static void main(String[] args) {
        Mytomcat server = new Mytomcat();
        server.start();
    }
    private void start(){
        try {
            //開啟一個(gè) Socket 服務(wù)端,并監(jiān)聽 8090 端口
            ServerSocket serverSocket = new ServerSocket(8090);
            do {
                //阻塞,直到有客戶端連接上,才會執(zhí)行后面的邏輯
                Socket socket = serverSocket.accept();
                //處理數(shù)據(jù)
                hander(socket);
            } while (true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * http response
     *  第一行 協(xié)議 返回狀態(tài)
     *  第二行 媒體類型 josn/html
     *  第三行 空
     *  內(nèi)容
     * @param socket
     */
    private void hander(Socket socket) throws IOException {
        //拼接返回的 request 報(bào)文
        StringBuilder responseBuilder = new StringBuilder();
        responseBuilder
		        //返回 200 狀態(tài)碼,表示請求成功
		        .append("HTTP/1.1 200 \r\n")
		        //告訴請求的客戶端,返回的內(nèi)容是 text/html 格式的
                .append("Content-Type: text/html\r\n")
                //首部字段和消息實(shí)體中間的空行
                .append("\r\n")
                //內(nèi)容部分
                .append("hello tomcat");
		//獲取客戶端通道的輸出流
        OutputStream outputStream = socket.getOutputStream();
        //往輸出流通道寫消息
        outputStream.write(responseBuilder.toString().getBytes());
        //流是有緩存機(jī)制的,寫消息的時(shí)候不一定立馬發(fā)出去,刷一下才能保證數(shù)據(jù)發(fā)送出去
        outputStream.flush();
        //關(guān)閉輸出流通道
        outputStream.close();
    }
}

上面的代碼初學(xué)者可以自己模仿著寫一個(gè),相信對 Http 會有很深刻的體驗(yàn)。代碼中主要是監(jiān)聽連接,客戶端連接后,根據(jù) Http 協(xié)議進(jìn)行字符串的拼接返回給客戶端,客戶端瀏覽器接收到是標(biāo)準(zhǔn)的 Http 格式就會進(jìn)行渲染。

4. 小結(jié)

這邊的代碼雖然很簡單,但是最核心的 Http 服務(wù)雛形已經(jīng)展示出來了,成熟的 Http 服務(wù)可以在這基礎(chǔ)上對以下模塊進(jìn)行優(yōu)化:

  • 針對請求事件的 線程 / IO 優(yōu)化;
  • Servlet 協(xié)議支持;
  • 配置獨(dú)立管理;
  • Http協(xié)議內(nèi)容完善(比如緩存機(jī)制);
  • 支持虛擬主機(jī)配置;
  • 支持代理;
  • rewrite 機(jī)制;
  • 安全認(rèn)證。