更好閱讀體驗:《理解 TCP 和 UDP》— By Gitbook git
TCP 是面向字節流的,但傳送的數據單元倒是報文段。算法
什麼是報文?
例如一個 100kb 的 HTML 文檔須要傳送到另一臺計算機,並不會整個文檔直接傳送過去,可能會切割成幾個部分,好比四個分別爲 25kb 的數據段。
而每一個數據段再加上一個 TCP 首部,就組成了 TCP 報文。
一共四個 TCP 報文,發送到另一個端。
另一端收到數據包,而後再剔除 TCP 首部,組裝起來。
等到四個數據包都收到了,就能還原出來一個完整的 HTML 文檔了。 緩存
在 OSI 的七層協議中,第二層(數據鏈路層)的數據叫「Frame」,第三層(網絡層)上的數據叫「Packet」,第四層(傳輸層)的數據叫「Segment」。服務器
TCP 報文 (Segment),包括首部和數據部分。 網絡
而 TCP 的所有功能都體如今它首部中各字段的做用,只有弄清 TCP 首部各字段的做用才能掌握 TCP 的工做原理。
TCP 報文段首部的前20個字節是固定的,後面有 4N 字節是根據須要而增長的。
下圖是把 TCP 報文中的首部放大來看。 tcp
TCP 的首部包括如下內容: 計算機網絡
下面展開來描述個字段的意義和做用。 3d
各佔 2 個 字節,共 4 個字節。
用來告知主機該報文段是來自哪裏以及傳送給哪一個應用程序(應用程序綁定了端口)的。
進行 TCP 通信時,客戶端一般使用系統自動選擇的臨時端口號,而服務器則使用知名服務端口號。 指針
佔 4 個字節。
TCP 是面向字節流的,在一個 TCP 鏈接中傳輸的字節流中的每一個字節都按照順序編號。
例如 100 kb 的 HTML 文檔數據,一共 102400 (100 * 1024) 個字節,那麼每個字節就都有了編號,整個文檔的編號的範圍是 0 ~ 102399。 cdn
序號字段值指的是本報文段所發送的數據的第一個字節的序號。
那麼 100 的 HTML 文檔分割成四個等分以後,
第一個 TCP 報文段包含的是第一個 25kb 的數據,0 ~ 25599 字節, 該報文的序號的值就是:0
第二個 TCP 報文段包含的是第二個 25kb 的數據,25600 ~ 51199 字節,該報文的序號的值就是:25600
......
根據 8 位 = 1 字節,那麼 4 個字節能夠表示的數值範圍:[0, 2^32],一共 2^32 (4294967296) 個序號。
序號增長到最大值的時候,下一個序號又回到了 0.
也就是說 TCP 協議可對 4GB 的數據進行編號,在通常狀況下可保證當序號重複使用時,舊序號的數據早已經經過網絡到達終點或者丟失了。
佔 4 個字節。
表示指望收到對方下一個報文段的序號值。
TCP 的可靠性,是創建在「每個數據報文都須要確認收到」的基礎之上的。
就是說,通信的任何一方在收到對方的一個報文以後,都要發送一個相對應的「確認報文」,來表達確認收到。
那麼,確認報文,就會包含確認號。
例如,通信的一方收到了第一個 25kb 的報文,該報文的 序號值=0,那麼就須要回覆一個確認報文,其中的確認號 = 25600.
佔 0.5 個字節 (4 位)。
這個字段其實是指出了 TCP 報文段的首部長度 ,它指出了 TCP報文段的數據起始處 距離 TCP報文的起始處 有多遠。(注意 數據起始處 和 報文起始處 的意思)
一個數據偏移量 = 4 byte,因爲 4 位二進制數能表示的最大十進制數字是 15,所以數據偏移的最大值是 60 byte,這也側面限制了 TCP 首部的最大長度。
佔 0.75 個字節 (6 位)。
保留爲從此使用,但目前應置爲 0。
標誌位,一共有 6 個,分別佔 1 位,共 6 位 。
每一位的值只有 0 和 1,分別表達不一樣意思。
當 URG = 1 的時候,表示緊急指針(Urgent Pointer)有效。
它告訴系統此報文段中有緊急數據,應儘快傳送,而不要按原來的排隊順序來傳送。
URG 要與首部中的 緊急指針 字段配合使用。
當 ACK = 1 的時候,確認號(Acknowledgemt Number)有效。
通常稱攜帶 ACK 標誌的 TCP 報文段爲「確認報文段」。
TCP 規定,在鏈接創建後全部傳送的報文段都必須把 ACK 設置爲 1。
當 PSH = 1 的時候,表示該報文段高優先級,接收方 TCP 應該儘快推送給接收應用程序,而不用等到整個 TCP 緩存都填滿了後再交付。
當 RST = 1 的時候,表示 TCP 鏈接中出現嚴重錯誤,須要釋放並從新創建鏈接。
通常稱攜帶 RST 標誌的 TCP 報文段爲「復位報文段」。
當 SYN = 1 的時候,代表這是一個請求鏈接報文段。
通常稱攜帶 SYN 標誌的 TCP 報文段爲「同步報文段」。
在 TCP 三次握手中的第一個報文就是同步報文段,在鏈接創建時用來同步序號。
對方若贊成創建鏈接,則應在響應的報文段中使 SYN = 1 和 ACK = 1。
當 FIN = 1 時,表示此報文段的發送方的數據已經發送完畢,並要求釋放 TCP 鏈接。
通常稱攜帶 FIN 的報文段爲「結束報文段」。
在 TCP 四次揮手釋放鏈接的時候,就會用到該標誌。
佔 2 字節。
該字段明確指出瞭如今容許對方發送的數據量,它告訴對方本端的 TCP 接收緩衝區還能容納多少字節的數據,這樣對方就能夠控制發送數據的速度。
窗口大小的值是指,從本報文段首部中的確認號算起,接收方目前容許對方發送的數據量。
例如,假如確認號是 701 ,窗口字段是 1000。這就代表,從 701 號算起,發送此報文段的一方還有接收 1000 (字節序號是 701 ~ 1700) 個字節的數據的接收緩存空間。
佔 2 個字節。
由發送端填充,接收端對 TCP 報文段執行 CRC 算法,以檢驗 TCP 報文段在傳輸過程當中是否損壞,若是損壞這丟棄。
檢驗範圍包括首部和數據兩部分,這也是 TCP 可靠傳輸的一個重要保障。
佔 2 個字節。
僅在 URG = 1 時纔有意義,它指出本報文段中的緊急數據的字節數。
當 URG = 1 時,發送方 TCP 就把緊急數據插入到本報文段數據的最前面,而在緊急數據後面的數據還是普通數據。
所以,緊急指針指出了緊急數據的末尾在報文段中的位置。