HTTP詳解

HTTP協(xié)議是“看不著明场、摸不著”的。因為在Java語言中午笛,有太多的HTTP相關(guān)的庫惭蟋,如:HTTPClient、HTTPUrlConnection药磺、Spring的RestTemplete等告组。因此在某種程度上從事Java相關(guān)的開發(fā)人員很難需要去深扒HTTP協(xié)議,而基本上都屬于會用就好的狀態(tài)癌佩。

編寫本文的思路正如下面的文章目錄木缝。

目錄

  • 一、HTTP簡介
  • 二围辙、什么是協(xié)議
    • 2.1 協(xié)議的定義
  • 三我碟、Wireshark網(wǎng)絡(luò)抓包工具
  • 四、HTTP協(xié)議
    • 4.1 前置知識
    • 4.2 請求協(xié)議結(jié)構(gòu)
      • 4.2.1 描述
      • 4.2.2 抓包查看
    • 4.3 響應(yīng)協(xié)議結(jié)構(gòu)
      • 4.3.1 描述
      • 4.3.2 抓包查看
    • 4.4 分包傳輸
      • 4.4.1 結(jié)構(gòu)圖
      • 4.4.2 優(yōu)點(diǎn)
      • 4.4.3 缺點(diǎn)
      • 4.4.4 抓包查看
    • 4.5 KeepAlive
      • 4.5.1 Tomcat對KeepAlive的支持
      • 4.5.2 TCP協(xié)議與HTTP協(xié)議中的KeepAlive區(qū)別
      • 4.5.3 如何復(fù)用長連接
      • 4.5.4 如何關(guān)閉長鏈接
      • 4.5.5 疑問待解決
      • 4.5.6 4.4 分包傳輸
  • 五姚建、HTTP協(xié)議如何解決TCP的粘包與拆包

一怎囚、HTTP簡介

HTTP中文名稱是超文本傳輸協(xié)議(英文:HyperText Transfer Protocol),HTTP是基于 TCP/IP 協(xié)議之上的應(yīng)用層協(xié)議桥胞,HTTP是萬維網(wǎng)數(shù)據(jù)通信的基礎(chǔ)。

因此考婴,在HTTP建立之前贩虾,需要先等客戶端與服務(wù)端建立TCP連接。

二沥阱、什么是協(xié)議

在了解具體的HTTP協(xié)議之前缎罢,最好還是先了解什么叫協(xié)議,這對之后的學(xué)習(xí)其它協(xié)議肯定會有幫助。

2.1 協(xié)議的定義

協(xié)議策精,網(wǎng)絡(luò)協(xié)議的簡稱舰始,網(wǎng)絡(luò)協(xié)議是通信計算機(jī)雙方必須共同遵從的一組約定。如怎么樣建立連接咽袜、怎么樣互相識別等丸卷。只有遵守這個約定,計算機(jī)之間才能相互通信交流询刹。它的三要素是:語法谜嫉、語義、時序凹联。

為了使數(shù)據(jù)在網(wǎng)絡(luò)上從源到達(dá)目的沐兰,網(wǎng)路通信的參與方必須遵循相同的規(guī)則,這套規(guī)則稱為協(xié)議(protocol)蔽挠,它最終體現(xiàn)在網(wǎng)絡(luò)上傳輸?shù)臄?shù)據(jù)包的格式住闯。

協(xié)議往往分為幾個層次進(jìn)行定義,分層定義是為了使某一層協(xié)議的改變不影響其他層次的協(xié)議澳淑。

備注:以上文字來源于百度百科

三比原、Wireshark網(wǎng)絡(luò)抓包工具

Wireshark是一個網(wǎng)絡(luò)封包分析軟件。網(wǎng)絡(luò)封包分析軟件的功能是擷取網(wǎng)絡(luò)封包偶惠,并盡可能顯示出最為詳細(xì)的網(wǎng)絡(luò)封包資料春寿。Wireshark使用WinPCAP作為接口,直接與網(wǎng)卡進(jìn)行數(shù)據(jù)報文交換忽孽。

在學(xué)習(xí)HTTP協(xié)議的過程中绑改,因為HTTP協(xié)議的是看不見摸不著的,這給學(xué)習(xí)帶來一定的難度兄一。因此有必要用Wireshark抓包工具抓取一個HTTP協(xié)議下來觀察厘线。

Wireshark官網(wǎng)地址:https://wireshark.en.softonic.com/
先看一下Wireshark的界面:

1.Wireshark1.png

顯而易見:Wireshark抓包界面中分為頂部的菜單欄、過濾欄出革、上造壮、中、下五個部分骂束;

  • 過濾欄:用于寫一些過濾條件耳璧,避免被抓的包太多展箱,導(dǎo)致眼花繚亂不方便觀察包
  • 上:請求列表旨枯,包含TCP、HTTP等等協(xié)議包
  • 中:一共有5個Item混驰。從上到下分別為:物理層攀隔、數(shù)據(jù)鏈路層皂贩、網(wǎng)絡(luò)層、傳輸層昆汹、應(yīng)用層明刷。有時候還會多一個Item,多的Item只是Wireshark將應(yīng)用層中攜帶的數(shù)據(jù)解析出來展示而已满粗,網(wǎng)絡(luò)包中實際沒有辈末。因此這一區(qū)域的數(shù)據(jù),Wireshark主要是用來展示更加人性化败潦、經(jīng)過加工后的數(shù)據(jù)本冲。
  • 下:十六進(jìn)制數(shù)據(jù),是真正網(wǎng)絡(luò)包中的數(shù)據(jù)劫扒;

四檬洞、HTTP協(xié)議

4.1 前置知識

在HTTP協(xié)議中,有很多的符號如:\n\r等沟饥,而也正是因為這些符號對HTTP協(xié)議解決拆包添怔、粘包提供了基礎(chǔ)

標(biāo)識 ASCII 描述 字符
CR 13 回車 \n
LF 10 換行 \r
SP 32 空格
COLON 58 冒號 :

4.2 請求協(xié)議結(jié)構(gòu)

4.2.1 描述

HTTP請求體中包含三個部分:① 請求行、② 請求頭(Header)贤旷、③ 請求正文(Body)

0.HTTP協(xié)議Request透視圖.png

概括為文字如下:

  • 請求行:

    包含三個部分:Method广料、URL、協(xié)議/版本幼驶,而這之前用空格隔開艾杏,在請求行的最后添加CRLF

  • 請求頭:

    包含若干個鍵值對(格式為:key:value),在每個鍵值對之間都用CRLF隔開盅藻,在整個請求頭的最后再加上一個CRLF购桑;也就是說最后一個鍵值對的最后會有兩個CRLF。

  • 請求正文:

    請求正文中主要是POST Method提交的數(shù)據(jù)氏淑,數(shù)據(jù)的格式可以有很多種勃蜘,具體什么格式實在請求頭中由Content-Type定義。在不考慮分包傳輸?shù)那闆r下假残,請求正文中數(shù)據(jù)的字節(jié)數(shù)由Content-Length指定缭贡。

4.2.2 抓包查看

2.Wireshark2.png

4.3 響應(yīng)協(xié)議結(jié)構(gòu)

4.3.1 描述

HTTP響應(yīng)體中包含三個部分:① 狀態(tài)行、② 響應(yīng)頭(Header)辉懒、③ 響應(yīng)正文(Body)

3.HTTP協(xié)議Response透視圖.png

概括為文字如下:

  • 響應(yīng)行:

    包含三個部分:協(xié)議/版本阳惹、響應(yīng)狀態(tài)碼、狀態(tài)碼描述符眶俩,而這之前用空格隔開穆端,在請求行的最后添加CRLF

  • 響應(yīng)頭:

    不說了,響應(yīng)頭格式同Request中的請求頭格式

  • 響應(yīng)正文:

    不說了仿便,響應(yīng)正文同Request中的請求正文

4.3.2 抓包查看

4.Wireshark4.png

看到這里体啰,有的小伙伴可能會提出問題:

問:在上圖中[響應(yīng)頭]與[響應(yīng)正文]之間是什么數(shù)據(jù)呢?

答:這些數(shù)據(jù)是Wireshark為了輔助展示出的一些指標(biāo)數(shù)據(jù)嗽仪。實際上荒勇,在網(wǎng)絡(luò)包中并沒有這些數(shù)據(jù),這里對比一下最下面的方塊闻坚,看一下網(wǎng)絡(luò)包中真正的數(shù)據(jù)沽翔。

問:在網(wǎng)絡(luò)分層中,Hypertext Transfer Protocol已經(jīng)是網(wǎng)絡(luò)模型中的應(yīng)用層了窿凤,那為什么上圖的抓包中仅偎,最下面還有一層:Line-base text data:text/plain(1 lines)

答:這個問題的答案其實和上一個問題的答案一致雳殊,這只是Wireshark為了展示的更加人性化橘沥,將數(shù)據(jù)抽離在了該層展示低而已,注意看最下面的紅色框框夯秃,在Header結(jié)束之后就是兩個CRLF座咆,緊接著就是數(shù)據(jù)(hello world!)了仓洼。

4.4 分包傳輸

在HTTP協(xié)議中介陶,除了將數(shù)據(jù)放在一個包中一次性發(fā)出,還可以通過分包方式將一個大批數(shù)據(jù)分在多個數(shù)據(jù)包中進(jìn)行傳輸色建。需要注意的是哺呜,分包傳輸使用的也是同一個Socket連接。
在Header中通過Transfer-Encoding: chunked進(jìn)行指定箕戳,該KV與Content-Length只能同時出現(xiàn)一個某残。
需要注意的是:在HTTP1.0版本協(xié)議中不支持分包。在HTTP1.1之后開始支持分包漂羊。

4.4.1 結(jié)構(gòu)圖

5.chunked.png

4.4.2 優(yōu)點(diǎn)

  • 當(dāng)響應(yīng)數(shù)據(jù)體量大時驾锰,避免瀏覽器出現(xiàn)忙等導(dǎo)致頁面出現(xiàn)長時間的空白
  • 當(dāng)要發(fā)送的數(shù)據(jù)長度很難計算時,為了保證吞吐量走越,可以先將一部分?jǐn)?shù)據(jù)通過一個子包先發(fā)出去

4.4.3 缺點(diǎn)

  • 協(xié)議比較復(fù)雜

4.4.4 抓包查看

6.Wireshark6.png

4.5 KeepAlive

HTTP協(xié)議如果不做特殊處理都是一種短連接椭豫,即為一次會話建立TCP/IP之后,客戶端與服務(wù)端基于TCP/IP的連接之上通過HTTP協(xié)議完成會話后旨指,連接也會被服務(wù)端斷開赏酥。下一次的HTTP請求,還是需要為這個請求進(jìn)行三次握手創(chuàng)建TCP連接谆构,用完之后還需要四次揮手?jǐn)嚅_TCP連接裸扶,這大大減少了傳輸效率。

而KeepAlive的產(chǎn)生就是為了彌補(bǔ)上述的不足搬素。

HTTP1.0版本中需要在Header中加入Connection: keep-alive來指定會話完畢之后不立即斷開連接呵晨,而是有一定的復(fù)用時間魏保。HTTP1.1版本中,默認(rèn)開啟該配置:Connection: keep-alive摸屠。

4.5.1 Tomcat對KeepAlive的支持

  • KeepAliveTimeout

    意義在于當(dāng)請求結(jié)束之后默認(rèn)要等待該值的時長谓罗,以達(dá)到復(fù)用的效果。

    在Tomcat9中季二,該參數(shù)值默認(rèn)等于ConnectionTimeout的時長檩咱,而ConnectionTimeout在server.xml中默認(rèn)是20000ms。ConnectionTimeout的含義在于:當(dāng)連接建立起之后胯舷,可以忍受多久的時間客戶端沒有發(fā)數(shù)據(jù)過來刻蚯。

    看一段Tomcat9的源碼:

    <attribute name="keepAliveTimeout" required="false">
      <p>The number of milliseconds this <strong>Connector</strong> will wait
      for another HTTP request before closing the connection. The default value
      is to use the value that has been set for the
      <strong>connectionTimeout</strong> attribute.
      Use a value of -1 to indicate no (i.e. infinite) timeout.</p>
    </attribute>
    

    但是需要注意,該值最好別設(shè)置的太久桑嘶,當(dāng)大流量打入之后可能會導(dǎo)致資源始終無法釋放炊汹。

    這里有一篇線上問題的復(fù)盤博客,可以參考一下:

    http://www.voycn.com/article/tomcat-connectiontimeout-lijie

  • MaxKeepAliveRequests

    Tomcat某個時刻最大能維護(hù)多少的長鏈接不翩,這個值在Tomcat9版本中默認(rèn)為100兵扬。

    看一段Tomcat9的源碼:

    <attribute name="maxKeepAliveRequests" required="false">
      <p>The maximum number of HTTP requests which can be pipelined until
      the connection is closed by the server. Setting this attribute to 1 will
      disable HTTP/1.0 keep-alive, as well as HTTP/1.1 keep-alive and
      pipelining. Setting this to -1 will allow an unlimited amount of
      pipelined or keep-alive HTTP requests.
      If not specified, this attribute is set to 100.</p>
    </attribute>
    

4.5.2 TCP協(xié)議與HTTP協(xié)議中的KeepAlive區(qū)別

需要注意的是:TCP協(xié)議中也有KeepAlive參數(shù),但是與HTTP的KeepAlive還是有區(qū)別的口蝠;

  • TCP-KeepAlive

    TCP的KeepAlive是為了連接逼髦樱活,該機(jī)制有三個重要的參數(shù):

    tcp_keepalive_intvl:泵钫幔活探測消息的發(fā)送頻率

    tcp_keepalive_probes:需要發(fā)送X次的探測消息但依然無效傲霸,則認(rèn)為連接斷開

    tcp_keepalive_time:最后一次數(shù)據(jù)交換到TCP第一次發(fā)送探針消息的間隔時間

  • HTTP-Keep-Alive

    HTTP發(fā)出響應(yīng)之后不要斷開連接,連接需要保持一段時間眉反,以達(dá)到復(fù)用的效果昙啄。

4.5.3 如何復(fù)用長連接

首先需要了解的是,復(fù)用到底復(fù)用的是什么寸五,看了上面的介紹梳凛,短連接中的每次請求都需要先進(jìn)行TCP的連接導(dǎo)致TCP鏈路無法復(fù)用,因此這里的復(fù)用其實是針對TCP鏈路的復(fù)用梳杏。

可以配合連接池韧拒,如HttpClient就對長連接具有管理的功能,注意這里的管理肯定是針對長連接了十性,短連接壓根就無法復(fù)用叛溢。

4.5.4 如何關(guān)閉長鏈接

當(dāng)TCP連接需要關(guān)閉時,只需要在Header頭中添加Connection: close即可劲适。

4.5.5 疑問待解決

Tomcat9版本中默認(rèn)KeepTimeout為20s楷掉,我也查看了一下SpringBoot對于Tomcat的配置,發(fā)現(xiàn)SpringBoot沒有對Tomcat參數(shù)做調(diào)整霞势,至少KeepTimeout用的就是Tomcat默認(rèn)值烹植。

那么在這樣的情況下斑鸦,KeepTimeout最終應(yīng)該為20s才對,但是在抓包過程中卻發(fā)現(xiàn)其值為60s.

抓包如下:


7.Wireshark7.jpg

4.5.6 從JVM層面判斷連接是否復(fù)用

TODO

五草雕、HTTP協(xié)議如何解決TCP的粘包與拆包

TCP協(xié)議鄙才,數(shù)據(jù)傳輸都是stream式的,數(shù)據(jù)之間是沒有流邊界的促绵,在這樣情況下自然就會出現(xiàn)粘包與拆包的問題。那么基于TCP之上的HTTP協(xié)議當(dāng)然也會面臨這樣的問題嘴纺,那它是如何解決的呢败晴?

了解了HTTP協(xié)議的結(jié)構(gòu)之后,解決粘包拆包的問題就迎刃而解了栽渴。

HTTP的請求與響應(yīng)尖坤,對于請求行、請求頭闲擦、響應(yīng)行慢味、響應(yīng)頭而言,都可以通過CRLF與空格作為流的邊界進(jìn)行讀取墅冷。

對于請求正文與響應(yīng)正文而言纯路,他們的字節(jié)長度在Header中的Content-Length中定義,假若寞忿,Header中沒有Content-Length屬性驰唬,取而代之的是Transfer-Encoding: chunked,那么就讀取每一個chunk的size腔彰,繼而再讀取size個byte叫编,知道讀取到last-chunk的size為0。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末霹抛,一起剝皮案震驚了整個濱河市搓逾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌杯拐,老刑警劉巖霞篡,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異藕施,居然都是意外死亡寇损,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門裳食,熙熙樓的掌柜王于貴愁眉苦臉地迎上來矛市,“玉大人,你說我怎么就攤上這事诲祸∽抢簦” “怎么了而昨?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長找田。 經(jīng)常有香客問我歌憨,道長,這世上最難降的妖魔是什么墩衙? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任务嫡,我火速辦了婚禮,結(jié)果婚禮上漆改,老公的妹妹穿的比我還像新娘心铃。我一直安慰自己,他們只是感情好挫剑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布去扣。 她就那樣靜靜地躺著,像睡著了一般樊破。 火紅的嫁衣襯著肌膚如雪愉棱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天哲戚,我揣著相機(jī)與錄音奔滑,去河邊找鬼。 笑死惫恼,一個胖子當(dāng)著我的面吹牛档押,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播祈纯,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼令宿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了腕窥?” 一聲冷哼從身側(cè)響起粒没,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎簇爆,沒想到半個月后癞松,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡入蛆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年响蓉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哨毁。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡枫甲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情想幻,我是刑警寧澤粱栖,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站脏毯,受9級特大地震影響闹究,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜食店,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一渣淤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吉嫩,春花似錦砂代、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽露戒。三九已至椒功,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間智什,已是汗流浹背动漾。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留荠锭,地道東北人旱眯。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像证九,于是被迫代替她去往敵國和親删豺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 何為http: 無狀態(tài)的超文本傳輸協(xié)議(HTTP愧怜,HyperText Transfer Protocol)是...
    每天都是幸運(yùn)的一天閱讀 772評論 0 6
  • HTTP網(wǎng)絡(luò)請求 對于android開發(fā)來說呀页,http是網(wǎng)絡(luò)開發(fā)中最為重要、使用頻率最高的手段拥坛。 HTTP請求原理...
    幻滅一只狼閱讀 7,166評論 0 11
  • 一蓬蝶、http協(xié)議的定義 HTTP是超文本傳輸協(xié)議的縮寫。是互聯(lián)網(wǎng)上使用最為廣泛的一種網(wǎng)絡(luò)協(xié)議猜惋,適用于www服務(wù)器傳...
    小黑測試員閱讀 671評論 0 0
  • 本文使用青花瓷軟件和Wireshark進(jìn)行抓包分析 Wireshark下載地址 點(diǎn)這里 Wireshark的使用:...
    AKyS佐毅閱讀 2,141評論 0 20
  • HTTP協(xié)議丸氛,即超文本傳輸協(xié)議(HyperText Transfer Protocol),是基于TCP協(xié)議的應(yīng)用層...
    renyjenny閱讀 343評論 0 0