深入 HTTP2(幀,消息,流)

http2 協(xié)議簡(jiǎn)介

h2 專注于性能,最大的目標(biāo)在于用戶和網(wǎng)站之間只用一條連接。其h2 的推出并沒(méi)有改變http1.1 的基本語(yǔ)義。h2的目的是響應(yīng)復(fù)用,頭部壓縮來(lái)提高極致的性能。
其特性在 之前的文章中也做過(guò)介紹 http://www.itdecent.cn/p/3ea9b33c4678

核心概念
  • 連接 Connection :1個(gè)TCP連接包含多個(gè)Stream。
  • 數(shù)據(jù)流 Stream :一個(gè)雙向通訊數(shù)據(jù)流,包含1條或多條 message。
  • 消息 Message :對(duì)應(yīng)HTTP/1 中的請(qǐng)求或者響應(yīng),包含一個(gè)或者多條 Frame
  • 數(shù)據(jù)幀 : 最小單位,以二進(jìn)制壓縮格式存放 HTTP/1 中的內(nèi)容。
    http2

    一個(gè)消息是由 Headers 幀和DATA 幀組成的。
    消息的組成

    流,消息,幀 之間的關(guān)系
    流,消息,幀 之間的關(guān)系

抓包可以看到 1號(hào) Stream 流 傳遞了 一個(gè) GET 請(qǐng)求。1號(hào) Stream 流也進(jìn)行了回復(fù)(HEADER+DATA)


http2抓包

在一條 Connection 中,不同的流可以穿插傳遞,但是同一條流的達(dá)到順序必須是有序的,比如1號(hào)流,流內(nèi)的 幀必須有序。
這就是傳輸中無(wú)序,接收時(shí)組裝。

多路復(fù)用

幀格式

每個(gè)幀標(biāo)準(zhǔn)為9個(gè)字節(jié) (可理解為幀頭)

幀格式

幀中指明了其所屬于哪一個(gè) Stream流 (Stream Identifier)其占了31 位。
由此可見(jiàn),一個(gè)幀中最重要的就是 Stream Id 了。其余的內(nèi)容為

  • Length : 代表整個(gè) frame 的長(zhǎng)度,用一個(gè) 24 位無(wú)符號(hào)整數(shù)表示
  • Type : 定義 frame 的類型。幀類型決定了幀主體的格式和語(yǔ)義,如果 type 為 unknown 應(yīng)該忽略或拋棄。
  • Flags :是為幀類型相關(guān)而預(yù)留的布爾標(biāo)識(shí)。標(biāo)識(shí)對(duì)于不同的幀類型賦予了不同的語(yǔ)義。
  • R: 是一個(gè)保留的比特位。這個(gè)比特的語(yǔ)義沒(méi)有定義,發(fā)送時(shí)它必須被設(shè)置為 (0x0), 接收時(shí)需要忽略。
  • Frame Payload : 是主體內(nèi)容,由幀類型決定

下圖為wireshark中抓取的幀,上述的幀格式可以對(duì)比找到


wireshark中的幀

正是將每一個(gè)幀關(guān)聯(lián)到流上。才實(shí)現(xiàn)了多路復(fù)用。這個(gè)多路復(fù)用指的是很多個(gè)流之間的幀隨意穿插。比如客戶端收到 1流的 1 幀,又收到了 2流的3幀,再收到了3流的4幀,1流的2幀,1流的3幀,3流的5幀。
注意。相同的流之內(nèi),其幀必須是按順序的。
看一下下面的圖。還是之前的抓包圖


http2抓包

有沒(méi)有發(fā)現(xiàn)除了 0 幀之外,為什么沒(méi)有偶數(shù)幀?1,3,5 。。。
這就是因?yàn)?由客戶端發(fā)起的連接,必須是奇數(shù)流。服務(wù)端發(fā)起的必須是偶數(shù)流
一般服務(wù)端推送算作是服務(wù)端發(fā)起的連接,也就會(huì)出現(xiàn)偶數(shù)流了。

要想實(shí)現(xiàn)并發(fā),其實(shí)就是建立多個(gè)流。因?yàn)閱蝹€(gè)流因?yàn)楸仨氻樞虬l(fā)送,所以沒(méi)有辦法做到并發(fā)。

  • 流狀態(tài)管理的約束性規(guī)定
    • 新建立的流ID必須大于曾經(jīng)建立過(guò)狀態(tài)為opened 或者 reserved 的流ID。
    • 在新建立的流ID發(fā)送幀時(shí),意味著更小ID為idle的流就必須置為closed了。
    • Stream ID 不能復(fù)用,長(zhǎng)連接耗盡的ID,只能通過(guò)重新建立TCP連接了。

Stream ID 為 0 的幀 是 控制幀,如setting,window_update,ping等幀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容