HTTP/TCP/IP協議詳解

HTTP 1.1 HTTP 2.0

HTTP站在TCP之上

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

基于tcp的長鏈接

http long-polling

http streaming

web socket

移動端HTTP現狀

iOS平臺

iOS系統是從iOS8開始才通過NSURLSession來支持SPDY的,iOS9+開始自動支持http2.0。實際上apple對http2.0非常有信心,推廣力度也很大。新版本ATS機制默認使用https來進行網絡傳輸。APN(Apple Push Notifiction)在iOS9上也已經是通過http2.0來實現的了。iOS9 sdk里的NSURLSession默認使用http2.0,而且對開發者來說是完全透明的,甚至沒有api來知道到底是用的哪個版本的http協議。

對于開發者來說到底怎么去配置最佳的http使用方案呢?在我看來,因app而異,主要從兩方面來考慮:一是app本身http流量是否大而且密集,二是開發團隊本身的技術條件。http2.0的部署相對容易很多,客戶端開發者甚至不用做什么改動,只需要使用iOS9的SDK編譯即可,但缺點是http2.0只能適用于iOS9的設備。SPDY的部署相對麻煩一些,但優點是可以兼顧iOS6+的設備。iOS端的SPDY可以使用twitter開發的CocoaSPDY方案,但有一點需要特別處理:

由于蘋果的TLS實現不支持NPN,所以通過NPN協商使用SPDY就無法通過默認443端口來實現。有兩種做法,一是客戶端和server同時約定好使用另一個端口號來做NPN協商,二是server這邊通過request header智能判斷客戶端是否支持SPDY而越過NPN協商過程。第一種方法會簡單一點,不過需要從框架層將所有的http請求都map到另一個port,url mapping可以參考我之前的一篇文章。twitter自己的網站twitter.com使用的是第二種方法。

瀏覽器端(比如Chrome),server端(比如nginx)都陸續打算放棄支持spdy了,畢竟google官方都宣布要停止維護了。spdy會是一個過渡方案,會隨著iOS9的普及會逐步消失,所以這部分的技術投入需要開發團隊自己去衡量。

Android平臺

android和iOS情況類似,http2.0只能在新系統下支持,spdy作為過渡方案仍然有存在的必要。

對于使用webview的app來說,需要基于chrome內核的webview才能支持spdy和http2.0,而android系統的webview是從android4.4(KitKat)才改成基于chrome內核的。

對于使用native api調用的http請求來說,okhttp是同時支持spdy和http2.0的可行方案。如果使用ALPN,okhttp要求android系統5.0+(實際上,android4.4上就有了ALPN的實現,不過有bug,知道5.0才正式修復),如果使用NPN,可以從android4.0+開始支持,不過NPN也是屬于將要被淘汰的協議。

TCP是面向連接的,可靠的字節流的協議。連接時需要三次握手,斷開時需要四次揮手。這是因為TCP是全雙工的,數據可以在兩端傳遞,所以斷開時都需要在每端單獨進行關閉,一方向的關閉通常是半關閉的,所以一端關閉時需要發送FIN來終止連接,收到后需要確認ACK給發送端。

TCP數據在IP數據報中的封裝為20字節的IP首部加上20字節TCP首部和TCP數據。

TCP/IP協議族

1.Frame: 物理層 比特流

2.Ethernet II:數據鏈路層 以太網幀頭部信息

3.IP網絡層? IP Packet 頭部信息

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

5.應用層 HTTP

網絡層次劃分為 標準的OSI七層模型,還有 TCP/IP四層協議 以及 TCP/IP五層協議。如圖:


Wireshark下

TCP協議

? TCP是一種面向連接的、可靠的基于字節流的傳輸層通信協議。TCP將用戶數據打包成報文段,它發送后啟動一個定時器,另一端收到的數據進行確認,對失序的數據重新排序、丟棄重復數據。

TCP報文首部,如下圖所示:

16位源端口號

16為目的端口號

Sequence number – 序號

Acknowledgment number – 確認號

Flags – 標志位

—Urgent pointer 緊急指針位

— Acknowledgment 確認位

— Push 急迫位

— Reset 重置位

— Syn 同步位

— Fin 終止位


a. 第一次握手標志位

localhost Seq=0 -> 博客地址

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

b. 第二次握手標志位

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

從標志位看出,確認位、同步位有值,在做應答(SYN+ACK):Syn 同步位為 1 、Acknowledgment 確認位為 1

c. 第三次握手標志位

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

從標志位看出,只有確認位有值,在做再次確認(SYN):Acknowledgment 確認位為 1

所以,一個完整的三次握手就是:請求(SYN) — 應答(SYN+ACK) — 再次確認(SYN)。

三次握手:


為什么需要“三次握手”

在謝希仁著《計算機網絡》第四版中講“三次握手”的目的是“為了防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤”。在另一部經典的《計算機網絡》一書中講“三次握手”的目的是為了解決“網絡中存在延遲的重復分組”的問題。這兩種不同的表述其實闡明的是同一個問題。

謝希仁版《計算機網絡》中的例子是這樣的,“已失效的連接請求報文段”的產生在這樣一種情況下:client發出的第一個連接請求報文段并沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以后的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連接請求報文段后,就誤認為是client再次發出的一個新的連接請求。于是就向client發出確認報文段,同意建立連接。假設不采用“三次握手”,那么只要server發出確認,新的連接就建立了。由于現在client并沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送數據。但server卻以為新的運輸連接已經建立,并一直等待client發來數據。這樣,server的很多資源就白白浪費掉了。采用“三次握手”的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由于收不到確認,就知道client并沒有要求建立連接。”。 主要目的防止server端一直等待,浪費資源。

四次揮手:

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

傳輸數據的時候,如果發送方傳輸的數據量超過了接收方的處理能力,那么接收方會出現丟包。為了避免出現此類問題,流量控制要求數據傳輸雙方在每次交互時聲明各自的接收窗口「rwnd」大小,用來表示自己最大能保存多少數據,這主要是針對接收方而言的,通俗點兒說就是讓發送方知道接收方能吃幾碗飯,如果窗口衰減到零,那么就說明吃飽了,必須消化消化,如果硬撐的話說不定會大小便失禁,那就是丟包了。

flow control

接收方和發送方的稱呼是相對的,如果站在用戶的角度看:當瀏覽網頁時,數據以下行為主,此時客戶端是接收方,服務端是發送方;當上傳文件時,數據以上行為主,此時客戶端是發送方,服務端是接收方。

1、流量控制是管理兩端的流量,以免會產生發送過塊導致收端溢出,或者因收端處理太快而浪費時間的狀態。用的是:滑動窗口,以字節為單位

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

合攏:表示已經收到相應字節的確認了

展開:表示允許緩存發送更多的字節

收縮(非常不希望出現的,某些實現是禁止的):表示本來可以發送的,現在不能發送;但是如果收縮的是那些已經發出的,就會有問題;為了避免,收端會等待到緩存中有更多緩存空間時才進行通信。

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

發端窗口大小 = min{ rwnd , cwnd };

3、關閉窗口:窗口縮回有個例外,就是發送rwnd=0表示暫時不愿意接收數據。這種情況下,發端不是把窗口收縮,二是停止發送數據。(為了比避免死鎖,會用一些探測報定時發送試探,見定時器一節)

4、問題:某些時候,由于發端或收端的數據很慢,會引起大量的1字節數據痛惜,浪費很多資源。

(1)、發端的進程產生數據很慢時候,時不時的來個1字節數據,那么TCP就會1字節1字節的發送,效率很低。

解決方法(Nagle算法):

a、將第一塊數據發出去

b、然后等到發送緩存有足夠多的數據(最大報文段長度),或者等到收端確認的ACK時再發送數據。

c、重復b的過程

(2)、收端進程由于消耗數據很慢,所以可能會有這么一種情況,收端會發送其窗口大小為1的信息,然后有是1字節的傳輸

解決辦法(2種)

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

b、推遲確認:在對收到的報文段確認之前等待到足夠的接收緩存,或者等待到一個時間段(現在一般定義500ms)


慢啟動

雖然流量控制可以避免發送方過載接收方,但是卻無法避免過載網絡,這是因為接收窗口「rwnd」只反映了服務器個體的情況,卻無法反映網絡整體的情況。

為了避免過載網絡的問題,慢啟動引入了擁塞窗口「cwnd」的概念,用來表示發送方在得到接收方確認前,最大允許傳輸的未經確認的數據。「cwnd」同「rwnd」相比不同的是:它只是發送方的一個內部參數,無需通知給接收方,其初始值往往比較小,然后隨著數據包被接收方確認,窗口成倍擴大,有點類似于拳擊比賽,開始時不了解敵情,往往是次拳試探,慢慢心里有底了,開始逐漸加大重拳進攻的力度。

Slow Start

在慢啟動的過程中,隨著「cwnd」的增加,可能會出現網絡過載,其外在表現就是丟包,一旦出現此類問題,「cwnd」的大小會迅速衰減,以便網絡能夠緩過來。

說明:網絡中實際傳輸的未經確認的數據大小取決于「rwnd」和「cwnd」中的小值。

T C P的 流 量 控 制 由 連 接 的 每 一 端 通 過 聲 明 的 窗 口 大 小 來 提 供 。 窗 口 大 小 為 字 節 數 , 起 始于確認序號字段指明的值,這個值是接收端正期望接收的字節。窗口大小是一個16 bit字段,因 而 窗 口 大 小 最 大 為6 5 5 3 5字節。在2 4 . 4節 我 們 將 看 到 新 的 窗 口 刻 度 選 項 , 它 允 許 這 個 值 按 比例變化以提供更大的窗口。檢驗和覆蓋了整個的T C P報文段:T C P首部和T C P數 據 。 這 是 一 個 強 制 性 的 字 段 , 一 定 是由發端計算和存儲,并由收端進行驗證。T C P檢驗和的計算和U D P檢 驗 和 的 計 算 相 似 , 使 用一 個 偽 首 部 。只有當U R G標志置1時 緊 急 指 針 才 有 效 。 緊 急 指 針 是 一 個 正 的 偏 移 量 , 和 序 號 字 段 中 的 值相加表示緊急數據最后一個字節的序號。T C P的 緊 急 方 式 是 發 送 端 向 另 一 端 發 送 緊 急 數 據 的一種方式。

擁塞避免

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,582評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,540評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,801評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,223評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,442評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,976評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,800評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,996評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,233評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,702評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容

  • 1.這篇文章不是本人原創的,只是個人為了對這部分知識做一個整理和系統的輸出而編輯成的,在此鄭重地向本文所引用文章的...
    SOMCENT閱讀 13,110評論 6 174
  • 個人認為,Goodboy1881先生的TCP /IP 協議詳解學習博客系列博客是一部非常精彩的學習筆記,這雖然只是...
    貳零壹柒_fc10閱讀 5,083評論 0 8
  • 傳輸層-TCP, TCP頭部結構 ,TCP序列號和確認號詳解 TCP主要解決下面的三個問題 1.數據的可靠傳輸...
    抓兔子的貓閱讀 4,537評論 1 46
  • 1.OkHttp源碼解析(一):OKHttp初階2 OkHttp源碼解析(二):OkHttp連接的"前戲"——HT...
    隔壁老李頭閱讀 20,936評論 24 176
  • TCP/IP協議 作者:xinyuans 本文為參考TCP/IP詳解卷一,某些知識點加上了作者自己的理解,如有錯誤...
    xinyuans閱讀 828評論 0 1