HTTP/TCP/IP協(xié)議詳解

HTTP 1.1 HTTP 2.0

HTTP站在TCP之上

理解http協(xié)議之前一定要對TCP有一定基礎(chǔ)的了解刊咳。HTTP是建立在TCP協(xié)議之上,TCP協(xié)議作為傳輸層協(xié)議其實(shí)離應(yīng)用層并不遠(yuǎn)。HTTP協(xié)議的瓶頸及其優(yōu)化技巧都是基于TCP協(xié)議本身的特性。比如TCP建立連接時(shí)三次握手有1.5個RTT(round-trip time)的延遲,為了避免每次請求的都經(jīng)歷握手帶來的延遲钱床,應(yīng)用層會選擇不同策略的http長鏈接方案。又比如TCP在建立連接的初期有慢啟動(slow start)的特性燕雁,所以連接的重用總是比新建連接性能要好诞丽。

基于tcp的長鏈接

http long-polling

http streaming

web socket

移動端HTTP現(xiàn)狀

iOS平臺

iOS系統(tǒng)是從iOS8開始才通過NSURLSession來支持SPDY的鲸拥,iOS9+開始自動支持http2.0拐格。實(shí)際上apple對http2.0非常有信心,推廣力度也很大刑赶。新版本ATS機(jī)制默認(rèn)使用https來進(jìn)行網(wǎng)絡(luò)傳輸捏浊。APN(Apple Push Notifiction)在iOS9上也已經(jīng)是通過http2.0來實(shí)現(xiàn)的了。iOS9 sdk里的NSURLSession默認(rèn)使用http2.0撞叨,而且對開發(fā)者來說是完全透明的金踪,甚至沒有api來知道到底是用的哪個版本的http協(xié)議。

對于開發(fā)者來說到底怎么去配置最佳的http使用方案呢牵敷?在我看來胡岔,因app而異,主要從兩方面來考慮:一是app本身http流量是否大而且密集枷餐,二是開發(fā)團(tuán)隊(duì)本身的技術(shù)條件靶瘸。http2.0的部署相對容易很多,客戶端開發(fā)者甚至不用做什么改動毛肋,只需要使用iOS9的SDK編譯即可怨咪,但缺點(diǎn)是http2.0只能適用于iOS9的設(shè)備。SPDY的部署相對麻煩一些润匙,但優(yōu)點(diǎn)是可以兼顧iOS6+的設(shè)備诗眨。iOS端的SPDY可以使用twitter開發(fā)的CocoaSPDY方案,但有一點(diǎn)需要特別處理:

由于蘋果的TLS實(shí)現(xiàn)不支持NPN孕讳,所以通過NPN協(xié)商使用SPDY就無法通過默認(rèn)443端口來實(shí)現(xiàn)匠楚。有兩種做法,一是客戶端和server同時(shí)約定好使用另一個端口號來做NPN協(xié)商厂财,二是server這邊通過request header智能判斷客戶端是否支持SPDY而越過NPN協(xié)商過程芋簿。第一種方法會簡單一點(diǎn),不過需要從框架層將所有的http請求都map到另一個port蟀苛,url mapping可以參考我之前的一篇文章益咬。twitter自己的網(wǎng)站twitter.com使用的是第二種方法。

瀏覽器端(比如Chrome),server端(比如nginx)都陸續(xù)打算放棄支持spdy了幽告,畢竟google官方都宣布要停止維護(hù)了梅鹦。spdy會是一個過渡方案,會隨著iOS9的普及會逐步消失冗锁,所以這部分的技術(shù)投入需要開發(fā)團(tuán)隊(duì)自己去衡量齐唆。

Android平臺

android和iOS情況類似,http2.0只能在新系統(tǒng)下支持冻河,spdy作為過渡方案仍然有存在的必要箍邮。

對于使用webview的app來說,需要基于chrome內(nèi)核的webview才能支持spdy和http2.0叨叙,而android系統(tǒng)的webview是從android4.4(KitKat)才改成基于chrome內(nèi)核的锭弊。

對于使用native api調(diào)用的http請求來說,okhttp是同時(shí)支持spdy和http2.0的可行方案擂错。如果使用ALPN味滞,okhttp要求android系統(tǒng)5.0+(實(shí)際上,android4.4上就有了ALPN的實(shí)現(xiàn)钮呀,不過有bug剑鞍,知道5.0才正式修復(fù)),如果使用NPN爽醋,可以從android4.0+開始支持蚁署,不過NPN也是屬于將要被淘汰的協(xié)議。

TCP是面向連接的蚂四,可靠的字節(jié)流的協(xié)議光戈。連接時(shí)需要三次握手,斷開時(shí)需要四次揮手证杭。這是因?yàn)門CP是全雙工的田度,數(shù)據(jù)可以在兩端傳遞,所以斷開時(shí)都需要在每端單獨(dú)進(jìn)行關(guān)閉解愤,一方向的關(guān)閉通常是半關(guān)閉的镇饺,所以一端關(guān)閉時(shí)需要發(fā)送FIN來終止連接,收到后需要確認(rèn)ACK給發(fā)送端送讲。

TCP數(shù)據(jù)在IP數(shù)據(jù)報(bào)中的封裝為20字節(jié)的IP首部加上20字節(jié)TCP首部和TCP數(shù)據(jù)奸笤。

TCP/IP協(xié)議族

1.Frame: 物理層 比特流

2.Ethernet II:數(shù)據(jù)鏈路層 以太網(wǎng)幀頭部信息

3.IP網(wǎng)絡(luò)層? IP Packet 頭部信息

4.傳輸層 TCP Data Segment 頭部信息

5.應(yīng)用層 HTTP

網(wǎng)絡(luò)層次劃分為 標(biāo)準(zhǔn)的OSI七層模型,還有 TCP/IP四層協(xié)議 以及 TCP/IP五層協(xié)議哼鬓。如圖:


Wireshark下

TCP協(xié)議

? TCP是一種面向連接的监右、可靠的基于字節(jié)流的傳輸層通信協(xié)議。TCP將用戶數(shù)據(jù)打包成報(bào)文段异希,它發(fā)送后啟動一個定時(shí)器健盒,另一端收到的數(shù)據(jù)進(jìn)行確認(rèn),對失序的數(shù)據(jù)重新排序、丟棄重復(fù)數(shù)據(jù)扣癣。

TCP報(bào)文首部惰帽,如下圖所示:

16位源端口號

16為目的端口號

Sequence number – 序號

Acknowledgment number – 確認(rèn)號

Flags – 標(biāo)志位

—Urgent pointer 緊急指針位

— Acknowledgment 確認(rèn)位

— Push 急迫位

— Reset 重置位

— Syn 同步位

— Fin 終止位


a. 第一次握手標(biāo)志位

localhost Seq=0 -> 博客地址

從標(biāo)志位看出,同步位有值父虑,在做請求(SYN):Syn 同步位為1

b. 第二次握手標(biāo)志位

博客地址 Seq=0 Ack=1 -> localhost

從標(biāo)志位看出该酗,確認(rèn)位、同步位有值士嚎,在做應(yīng)答(SYN+ACK):Syn 同步位為 1 呜魄、Acknowledgment 確認(rèn)位為 1

c. 第三次握手標(biāo)志位

localhost Seq=1 Ack=1 ->? (注: Seq=Seq+1)

從標(biāo)志位看出,只有確認(rèn)位有值莱衩,在做再次確認(rèn)(SYN):Acknowledgment 確認(rèn)位為 1

所以爵嗅,一個完整的三次握手就是:請求(SYN) — 應(yīng)答(SYN+ACK) — 再次確認(rèn)(SYN)。

三次握手:


為什么需要“三次握手”

在謝希仁著《計(jì)算機(jī)網(wǎng)絡(luò)》第四版中講“三次握手”的目的是“為了防止已失效的連接請求報(bào)文段突然又傳送到了服務(wù)端膳殷,因而產(chǎn)生錯誤”操骡。在另一部經(jīng)典的《計(jì)算機(jī)網(wǎng)絡(luò)》一書中講“三次握手”的目的是為了解決“網(wǎng)絡(luò)中存在延遲的重復(fù)分組”的問題。這兩種不同的表述其實(shí)闡明的是同一個問題赚窃。

謝希仁版《計(jì)算機(jī)網(wǎng)絡(luò)》中的例子是這樣的,“已失效的連接請求報(bào)文段”的產(chǎn)生在這樣一種情況下:client發(fā)出的第一個連接請求報(bào)文段并沒有丟失岔激,而是在某個網(wǎng)絡(luò)結(jié)點(diǎn)長時(shí)間的滯留了勒极,以致延誤到連接釋放以后的某個時(shí)間才到達(dá)server。本來這是一個早已失效的報(bào)文段虑鼎。但server收到此失效的連接請求報(bào)文段后辱匿,就誤認(rèn)為是client再次發(fā)出的一個新的連接請求。于是就向client發(fā)出確認(rèn)報(bào)文段炫彩,同意建立連接匾七。假設(shè)不采用“三次握手”,那么只要server發(fā)出確認(rèn)江兢,新的連接就建立了昨忆。由于現(xiàn)在client并沒有發(fā)出建立連接的請求,因此不會理睬server的確認(rèn)杉允,也不會向server發(fā)送數(shù)據(jù)邑贴。但server卻以為新的運(yùn)輸連接已經(jīng)建立,并一直等待client發(fā)來數(shù)據(jù)叔磷。這樣拢驾,server的很多資源就白白浪費(fèi)掉了。采用“三次握手”的辦法可以防止上述現(xiàn)象發(fā)生改基。例如剛才那種情況繁疤,client不會向server的確認(rèn)發(fā)出確認(rèn)。server由于收不到確認(rèn),就知道client并沒有要求建立連接稠腊“钙#”。 主要目的防止server端一直等待麻养,浪費(fèi)資源褐啡。

四次揮手:

流量控制(滑動窗口協(xié)議)

傳輸數(shù)據(jù)的時(shí)候,如果發(fā)送方傳輸?shù)臄?shù)據(jù)量超過了接收方的處理能力鳖昌,那么接收方會出現(xiàn)丟包备畦。為了避免出現(xiàn)此類問題,流量控制要求數(shù)據(jù)傳輸雙方在每次交互時(shí)聲明各自的接收窗口「rwnd」大小许昨,用來表示自己最大能保存多少數(shù)據(jù)懂盐,這主要是針對接收方而言的,通俗點(diǎn)兒說就是讓發(fā)送方知道接收方能吃幾碗飯糕档,如果窗口衰減到零莉恼,那么就說明吃飽了,必須消化消化速那,如果硬撐的話說不定會大小便失禁俐银,那就是丟包了。

flow control

接收方和發(fā)送方的稱呼是相對的端仰,如果站在用戶的角度看:當(dāng)瀏覽網(wǎng)頁時(shí)捶惜,數(shù)據(jù)以下行為主,此時(shí)客戶端是接收方荔烧,服務(wù)端是發(fā)送方吱七;當(dāng)上傳文件時(shí),數(shù)據(jù)以上行為主鹤竭,此時(shí)客戶端是發(fā)送方踊餐,服務(wù)端是接收方。

1臀稚、流量控制是管理兩端的流量吝岭,以免會產(chǎn)生發(fā)送過塊導(dǎo)致收端溢出,或者因收端處理太快而浪費(fèi)時(shí)間的狀態(tài)烁涌。用的是:滑動窗口苍碟,以字節(jié)為單位

2、窗口有3種動作:展開(右邊向右)撮执,合攏(左邊向右)微峰,收縮(右邊向左)這三種動作受接收端的控制。

合攏:表示已經(jīng)收到相應(yīng)字節(jié)的確認(rèn)了

展開:表示允許緩存發(fā)送更多的字節(jié)

收縮(非常不希望出現(xiàn)的抒钱,某些實(shí)現(xiàn)是禁止的):表示本來可以發(fā)送的蜓肆,現(xiàn)在不能發(fā)送颜凯;但是如果收縮的是那些已經(jīng)發(fā)出的,就會有問題仗扬;為了避免症概,收端會等待到緩存中有更多緩存空間時(shí)才進(jìn)行通信。

發(fā)端窗口的大小取決于收端的窗口大小rwnd(TCP報(bào)文的窗口大小字段)和擁塞窗口大小cwnd(見擁塞控制)

發(fā)端窗口大小 = min{ rwnd , cwnd };

3早芭、關(guān)閉窗口:窗口縮回有個例外彼城,就是發(fā)送rwnd=0表示暫時(shí)不愿意接收數(shù)據(jù)。這種情況下退个,發(fā)端不是把窗口收縮募壕,二是停止發(fā)送數(shù)據(jù)。(為了比避免死鎖语盈,會用一些探測報(bào)定時(shí)發(fā)送試探舱馅,見定時(shí)器一節(jié))

4、問題:某些時(shí)候刀荒,由于發(fā)端或收端的數(shù)據(jù)很慢代嗤,會引起大量的1字節(jié)數(shù)據(jù)痛惜,浪費(fèi)很多資源缠借。

(1)干毅、發(fā)端的進(jìn)程產(chǎn)生數(shù)據(jù)很慢時(shí)候,時(shí)不時(shí)的來個1字節(jié)數(shù)據(jù)烈炭,那么TCP就會1字節(jié)1字節(jié)的發(fā)送溶锭,效率很低。

解決方法(Nagle算法):

a符隙、將第一塊數(shù)據(jù)發(fā)出去

b、然后等到發(fā)送緩存有足夠多的數(shù)據(jù)(最大報(bào)文段長度)垫毙,或者等到收端確認(rèn)的ACK時(shí)再發(fā)送數(shù)據(jù)霹疫。

c、重復(fù)b的過程

(2)综芥、收端進(jìn)程由于消耗數(shù)據(jù)很慢丽蝎,所以可能會有這么一種情況,收端會發(fā)送其窗口大小為1的信息膀藐,然后有是1字節(jié)的傳輸

解決辦法(2種)

a屠阻、Clark方法:在接收緩存的一半變空,或者有足夠空間放最大報(bào)文長度之前额各,宣告接收窗口大小為0

b国觉、推遲確認(rèn):在對收到的報(bào)文段確認(rèn)之前等待到足夠的接收緩存,或者等待到一個時(shí)間段(現(xiàn)在一般定義500ms)


慢啟動

雖然流量控制可以避免發(fā)送方過載接收方虾啦,但是卻無法避免過載網(wǎng)絡(luò)麻诀,這是因?yàn)榻邮沾翱凇竢wnd」只反映了服務(wù)器個體的情況痕寓,卻無法反映網(wǎng)絡(luò)整體的情況。

為了避免過載網(wǎng)絡(luò)的問題蝇闭,慢啟動引入了擁塞窗口「cwnd」的概念呻率,用來表示發(fā)送方在得到接收方確認(rèn)前,最大允許傳輸?shù)奈唇?jīng)確認(rèn)的數(shù)據(jù)呻引±裾蹋「cwnd」同「rwnd」相比不同的是:它只是發(fā)送方的一個內(nèi)部參數(shù),無需通知給接收方逻悠,其初始值往往比較小元践,然后隨著數(shù)據(jù)包被接收方確認(rèn),窗口成倍擴(kuò)大蹂风,有點(diǎn)類似于拳擊比賽卢厂,開始時(shí)不了解敵情,往往是次拳試探惠啄,慢慢心里有底了慎恒,開始逐漸加大重拳進(jìn)攻的力度。

Slow Start

在慢啟動的過程中撵渡,隨著「cwnd」的增加融柬,可能會出現(xiàn)網(wǎng)絡(luò)過載,其外在表現(xiàn)就是丟包趋距,一旦出現(xiàn)此類問題粒氧,「cwnd」的大小會迅速衰減,以便網(wǎng)絡(luò)能夠緩過來节腐。

說明:網(wǎng)絡(luò)中實(shí)際傳輸?shù)奈唇?jīng)確認(rèn)的數(shù)據(jù)大小取決于「rwnd」和「cwnd」中的小值外盯。

T C P的 流 量 控 制 由 連 接 的 每 一 端 通 過 聲 明 的 窗 口 大 小 來 提 供 。 窗 口 大 小 為 字 節(jié) 數(shù) 翼雀, 起 始于確認(rèn)序號字段指明的值饱苟,這個值是接收端正期望接收的字節(jié)。窗口大小是一個16 bit字段狼渊,因 而 窗 口 大 小 最 大 為6 5 5 3 5字節(jié)箱熬。在2 4 . 4節(jié) 我 們 將 看 到 新 的 窗 口 刻 度 選 項(xiàng) , 它 允 許 這 個 值 按 比例變化以提供更大的窗口狈邑。檢驗(yàn)和覆蓋了整個的T C P報(bào)文段:T C P首部和T C P數(shù) 據(jù) 城须。 這 是 一 個 強(qiáng) 制 性 的 字 段 , 一 定 是由發(fā)端計(jì)算和存儲米苹,并由收端進(jìn)行驗(yàn)證糕伐。T C P檢驗(yàn)和的計(jì)算和U D P檢 驗(yàn) 和 的 計(jì) 算 相 似 , 使 用一 個 偽 首 部 驱入。只有當(dāng)U R G標(biāo)志置1時(shí) 緊 急 指 針 才 有 效 赤炒。 緊 急 指 針 是 一 個 正 的 偏 移 量 氯析, 和 序 號 字 段 中 的 值相加表示緊急數(shù)據(jù)最后一個字節(jié)的序號。T C P的 緊 急 方 式 是 發(fā) 送 端 向 另 一 端 發(fā) 送 緊 急 數(shù) 據(jù) 的一種方式莺褒。

擁塞避免

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掩缓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子遵岩,更是在濱河造成了極大的恐慌你辣,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尘执,死亡現(xiàn)場離奇詭異舍哄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)誊锭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門表悬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丧靡,你說我怎么就攤上這事蟆沫。” “怎么了温治?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵饭庞,是天一觀的道長。 經(jīng)常有香客問我熬荆,道長舟山,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任卤恳,我火速辦了婚禮累盗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘突琳。我一直安慰自己幅骄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布本今。 她就那樣靜靜地躺著,像睡著了一般主巍。 火紅的嫁衣襯著肌膚如雪冠息。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天孕索,我揣著相機(jī)與錄音逛艰,去河邊找鬼。 笑死搞旭,一個胖子當(dāng)著我的面吹牛散怖,可吹牛的內(nèi)容都是我干的菇绵。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼镇眷,長吁一口氣:“原來是場噩夢啊……” “哼咬最!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起欠动,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤永乌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后具伍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體翅雏,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年人芽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了望几。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡萤厅,死狀恐怖橄抹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情祈坠,我是刑警寧澤害碾,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站赦拘,受9級特大地震影響慌随,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜躺同,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一阁猜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蹋艺,春花似錦剃袍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至涛救,卻和暖如春畏邢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背检吆。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工舒萎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蹭沛。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓臂寝,卻偏偏與公主長得像章鲤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子咆贬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

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

  • 1.這篇文章不是本人原創(chuàng)的败徊,只是個人為了對這部分知識做一個整理和系統(tǒng)的輸出而編輯成的,在此鄭重地向本文所引用文章的...
    SOMCENT閱讀 13,068評論 6 174
  • 個人認(rèn)為素征,Goodboy1881先生的TCP /IP 協(xié)議詳解學(xué)習(xí)博客系列博客是一部非常精彩的學(xué)習(xí)筆記集嵌,這雖然只是...
    貳零壹柒_fc10閱讀 5,054評論 0 8
  • 傳輸層-TCP, TCP頭部結(jié)構(gòu) 御毅,TCP序列號和確認(rèn)號詳解 TCP主要解決下面的三個問題 1.數(shù)據(jù)的可靠傳輸...
    抓兔子的貓閱讀 4,522評論 1 46
  • 1.OkHttp源碼解析(一):OKHttp初階2 OkHttp源碼解析(二):OkHttp連接的"前戲"——HT...
    隔壁老李頭閱讀 20,852評論 24 176
  • TCP/IP協(xié)議 作者:xinyuans 本文為參考TCP/IP詳解卷一根欧,某些知識點(diǎn)加上了作者自己的理解,如有錯誤...
    xinyuans閱讀 810評論 0 1