更好閱讀體驗:《理解 TCP 和 UDP》— By Gitbookgit
TCP 是面向字節流的,但傳送的數據單元倒是報文段。算法
什麼是報文?
例如一個 100kb 的 HTML 文檔須要傳送到另一臺計算機,並不會整個文檔直接傳送過去,可能會切割成幾個部分,好比四個分別爲 25kb 的數據段。
而每一個數據段再加上一個 TCP 首部,就組成了 TCP 報文。
一共四個 TCP 報文,發送到另一個端。
另一端收到數據包,而後再剔除 TCP 首部,組裝起來。
等到四個數據包都收到了,就能還原出來一個完整的 HTML 文檔了。 緩存
在 OSI 的七層協議中,第二層(數據鏈路層)的數據叫「Frame」,第三層(網絡層)上的數據叫「Packet」,第四層(傳輸層)的數據叫「Segment」。服務器
TCP 報文 (Segment),包括首部和數據部分。 網絡
而 TCP 的所有功能都體如今它首部中各字段的做用,只有弄清 TCP 首部各字段的做用才能掌握 TCP 的工做原理。
TCP 報文段首部的前20個字節是固定的,後面有 4N 字節是根據須要而增長的。
下圖是把 TCP 報文中的首部放大來看。 tcp
TCP 的首部包括如下內容:spa
源端口 source port計算機網絡
目的端口 destination port指針
序號 sequence number開發
確認號 acknowledgment number
數據偏移 offset
保留 reserved
標誌位 tcp flags
窗口大小 window size
檢驗和 checksum
緊急指針 urgent pointer
選項 tcp options
下面展開來描述個字段的意義和做用。
各佔 2 個 字節,共 4 個字節。
用來告知主機該報文段是來自哪裏以及傳送給哪一個應用程序(應用程序綁定了端口)的。
進行 TCP 通信時,客戶端一般使用系統自動選擇的臨時端口號,而服務器則使用知名服務端口號。
佔 4 個字節。
TCP 是面向字節流的,在一個 TCP 鏈接中傳輸的字節流中的每一個字節都按照順序編號。
例如 100 kb 的 HTML 文檔數據,一共 102400 (100 * 1024) 個字節,那麼每個字節就都有了編號,整個文檔的編號的範圍是 0 ~ 102399。
序號字段值指的是本報文段所發送的數據的第一個字節的序號。
那麼 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 就把緊急數據插入到本報文段數據的最前面,而在緊急數據後面的數據還是普通數據。
所以,緊急指針指出了緊急數據的末尾在報文段中的位置。