第七色在线视频,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)一個簡單的 Web 服務(wù)器,加深體驗(yàn) Web 服務(wù)和 Http 協(xié)議的原理。

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

1.1 監(jiān)聽連接

瀏覽器每發(fā)起一次請求都需要跟服務(wù)端建立連接,服務(wù)端要時刻監(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ā)送方跟接收方都需要按照這個格式來拼接和拆解內(nèi)容。我們要實(shí)現(xiàn)一個 Web 服務(wù),了解這個是最基本的要素。

以下截圖的報(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ù)器收到客戶端的請求后,就會有一個 Http 的響應(yīng)消息,Http 響應(yīng)也由 4 部分組成,分別是:狀態(tài)行、響應(yīng)頭、空行 和 響應(yīng)實(shí)體。
response

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

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 {
            //開啟一個 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ī)制的,寫消息的時候不一定立馬發(fā)出去,刷一下才能保證數(shù)據(jù)發(fā)送出去
        outputStream.flush();
        //關(guān)閉輸出流通道
        outputStream.close();
    }
}

上面的代碼初學(xué)者可以自己模仿著寫一個,相信對 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)證。