HTTP定義
HTTP構(gòu)建于TCP/IP協(xié)議之上即硼,默認(rèn)端口號是80。一般來說镐捧,由HTTP客戶端發(fā)起一個(gè)請求遭赂,創(chuàng)建一個(gè)到服務(wù)器指定端口(默認(rèn)是80端口)的TCP連接循诉。HTTP服務(wù)器則在那個(gè)端口監(jiān)聽客戶端的請求。一旦收到請求撇他,服務(wù)器會向客戶端返回一個(gè)狀態(tài)茄猫,比如"HTTP/1.1 200 OK",以及返回的內(nèi)容困肩,如請求的文件划纽、錯(cuò)誤消息、或者其它信息锌畸。
HTTP請求方法有多種勇劣,一般常用的是GET,POST潭枣,PUT比默,DELETE。
每個(gè)請求一般包括以下內(nèi)容
請求報(bào)文(請求行盆犁,請求頭部命咐,空行,請求包體)
- 請求行
由請求方法字段谐岁、URL 字段 和HTTP 協(xié)議版本字段 3 個(gè)部分組成醋奠,他們之間使用空格隔開。常用的 HTTP 請求方法有 GET伊佃、POST窜司。 - 請求頭部
為請求報(bào)文添加了一些附加信息,由“key/value”對組成航揉,每行一對塞祈,請求頭部通知服務(wù)器有關(guān)于客戶端請求的信息,典型的請求頭有:如帅涂,User-Agent --- 請求的瀏覽器類型 - 空行
表示最后一個(gè)請求頭部之后是一個(gè)空行织咧,發(fā)送回車符和換行符胀葱,通知服務(wù)器以下不再有請求頭部,因?yàn)轭^部是由多個(gè)“key/value”對組成笙蒙,空行的作用表示結(jié)束。 - 請求包體
請求包體不在GET方法中使用庆锦,而是POST方法中使用捅位。
GET方法的請求報(bào)文示例
需要注意的是, GET 和 POST 的一個(gè)主要區(qū)別是請求附帶的數(shù)據(jù)一個(gè)在URL里搂抒,一個(gè)在 HTTP 包的請求包體里艇搀,POST請求附帶的數(shù)據(jù)一般支持form、json求晶、xml等數(shù)據(jù)格式焰雕。這個(gè)格式由請求頭部
Content-Type
來規(guī)定。
響應(yīng)報(bào)文(狀態(tài)行芳杏,響應(yīng)頭部矩屁,空行,響應(yīng)包體)
由狀態(tài)行爵赵、響應(yīng)頭部吝秕、空行、響應(yīng)包體4個(gè)部分組成空幻。
- 狀態(tài)行
由HTTP 協(xié)議版本字段烁峭、狀態(tài)碼(如404)和狀態(tài)碼的描述文本3個(gè)部分組成 - 響應(yīng)頭部
由“key/value”對組成,每行一對 - 空行
最后一個(gè)響應(yīng)頭部之后是一個(gè)空行秕铛,發(fā)送回車符和換行符约郁,通知服務(wù)器以下不再有響應(yīng)頭部。 - 響應(yīng)包體
服務(wù)器返回給客戶端的文本信息但两。
響應(yīng)報(bào)文示例
Keep-Alive模式
由上面的示例可以看到里面的請求頭部和響應(yīng)頭部都有一個(gè)key-valueConnection: Keep-Alive
鬓梅,這個(gè)鍵值對的作用是讓HTTP保持連接狀態(tài),因?yàn)镠TTP 協(xié)議采用“請求-應(yīng)答”模式镜遣,當(dāng)使用普通模式己肮,即非 Keep-Alive 模式時(shí),每個(gè)請求/應(yīng)答客戶和服務(wù)器都要新建一個(gè)連接悲关,完成之后立即斷開連接(HTTP 協(xié)議為無連接的協(xié)議)谎僻;當(dāng)使用 Keep-Alive 模式時(shí),Keep-Alive 功能使客戶端到服務(wù)器端的連接持續(xù)有效寓辱。
在HTTP 1.1版本后艘绍,默認(rèn)都開啟Keep-Alive模式,只有加入加入 Connection: close
才關(guān)閉連接秫筏,當(dāng)然也可以設(shè)置Keep-Alive模式的屬性诱鞠,例如 Keep-Alive: timeout=5, max=100
挎挖,表示這個(gè)TCP通道可以保持5秒,max=100航夺,表示這個(gè)長連接最多接收100次請求就斷開蕉朵。
Keep-Alive模式下如何知道某一次數(shù)據(jù)傳輸結(jié)束
如果不是Keep-Alive模式,HTTP協(xié)議中客戶端發(fā)送一個(gè)請求阳掐,服務(wù)器響應(yīng)其請求始衅,返回?cái)?shù)據(jù)。服務(wù)器通常在發(fā)送回所請求的數(shù)據(jù)之后就關(guān)閉連接缭保。這樣客戶端讀數(shù)據(jù)時(shí)會返回EOF(-1)汛闸,就知道數(shù)據(jù)已經(jīng)接收完全了。
但是如果開啟了 Keep-Alive模式艺骂,那么客戶端如何知道某一次的響應(yīng)結(jié)束了呢诸老?
以下有兩個(gè)方法
如果是靜態(tài)的響應(yīng)數(shù)據(jù),可以通過判斷響應(yīng)頭部中的Content-Length 字段钳恕,判斷數(shù)據(jù)達(dá)到這個(gè)大小就知道數(shù)據(jù)傳輸結(jié)束了别伏。
但是返回的數(shù)據(jù)是動(dòng)態(tài)變化的,服務(wù)器不能第一時(shí)間知道數(shù)據(jù)長度苞尝,這樣就沒有 Content-Length 關(guān)鍵字了畸肆。這種情況下,服務(wù)器是分塊傳輸數(shù)據(jù)的宙址,
Transfer-Encoding:chunk
轴脐,這時(shí)候就要根據(jù)傳輸?shù)臄?shù)據(jù)塊chunk來判斷,數(shù)據(jù)傳輸結(jié)束的時(shí)候抡砂,最后的一個(gè)數(shù)據(jù)塊chunk的長度是0大咱。
TCP的Keep Alive
HTTP的Keep-Alive與TCP的Keep Alive,有些不同注益,兩者意圖不一樣碴巾。前者主要是 TCP連接復(fù)用,避免建立過多的TCP連接丑搔。而TCP的Keep Alive的意圖是在于保持TCP連接的存活厦瓢,就是發(fā)送心跳包。隔一段時(shí)間給連接對端發(fā)送一個(gè)探測包啤月,如果收到對方回應(yīng)的 ACK煮仇,則認(rèn)為連接還是存活的,在超過一定重試次數(shù)之后還是沒有收到對方的回應(yīng)谎仲,則丟棄該 TCP 連接浙垫。
短連接
所謂短連接,及連接只保持在數(shù)據(jù)傳輸過程,請求發(fā)起夹姥,連接建立杉武,數(shù)據(jù)返回,連接關(guān)閉辙售。它適用于一些實(shí)時(shí)數(shù)據(jù)請求轻抱,配合輪詢來進(jìn)行新舊數(shù)據(jù)的更替。
長連接
長連接便是在連接發(fā)起后旦部,在請求關(guān)閉連接前客戶端與服務(wù)端都保持連接十拣,實(shí)質(zhì)是保持這個(gè)通信管道,之后便可以對其進(jìn)行復(fù)用志鹃。
它適用于涉及消息推送,請求頻繁的場景(直播泽西,流媒體)曹铃。連接建立后,在該連接下的所有請求都可以重用這個(gè)長連接管道捧杉,避免了頻繁了連接請求陕见,提升了效率。
使用HTTP建立長連接
當(dāng)需要建立 HTTP 長連接時(shí)味抖,HTTP 請求頭將包含如下內(nèi)容:
Connection: Keep-Alive
如果服務(wù)端同意建立長連接评甜,HTTP 響應(yīng)頭也將包含如下內(nèi)容:
Connection: Keep-Alive
當(dāng)需要關(guān)閉連接時(shí),HTTP 頭中會包含如下內(nèi)容:
Connection: Close
HTTP版本區(qū)別
HTTP/1.0與HTTP/1.1
主要體現(xiàn)在長連接與部分發(fā)送上面
- 在 HTTP/1.0 時(shí)代仔涩,每一個(gè)請求都會重新建立一個(gè) TCP 連接忍坷,一旦響應(yīng)返回,就關(guān)閉連接熔脂,這種就是短連接佩研,HTTP/1.1版本就支持Keep-Alive 模式,實(shí)現(xiàn)長連接了霞揉。
- HTTP 1.1支持只發(fā)送header信息(不帶任何body信息)旬薯,如果服務(wù)器認(rèn)為客戶端有權(quán)限請求服務(wù)器,則返回100适秩,否則返回401绊序。客戶端如果接受到100秽荞,才開始把請求body發(fā)送到服務(wù)器骤公。這樣當(dāng)服務(wù)器返回401的時(shí)候,客戶端就可以不用發(fā)送請求body了蚂会,節(jié)約了帶寬淋样。
HTTP/1.1 與HTTP/2.0
主要體現(xiàn)在多路復(fù)用上面。
HTTP2.0使用了多路復(fù)用的技術(shù)胁住,做到同一個(gè)連接并發(fā)處理多個(gè)請求趁猴,而且并發(fā)請求的數(shù)量比HTTP1.1大了好幾個(gè)數(shù)量級刊咳。當(dāng)然HTTP1.1也可以多建立幾個(gè)TCP連接,來支持處理更多并發(fā)的請求儡司,但是創(chuàng)建TCP連接本身也是有開銷的娱挨。
支持header數(shù)據(jù)壓縮
支持服務(wù)器推送
參考文章
https://hit-alibaba.github.io/interview/basic/network/HTTP.html
https://blog.csdn.net/linsongbin1/article/details/54980801