1. 程式人生 > >Linux 網路程式設計——TCP 和 UDP 資料報格式詳解

Linux 網路程式設計——TCP 和 UDP 資料報格式詳解

TCP 報文格式

TCP(Transmission Control Protocol 傳輸控制協議)是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協議。

TCP 報文段的報頭有 10 個必需的欄位和 1 個可選欄位。報頭至少為 20 位元組。報頭後面的資料是可選項。

1)源埠(16位)

標識傳送報文的計算機埠或程序。一個 TCP 報文段必須包括源埠號,使目的主機知道應該向何處傳送確認報文。

2)目的埠(16位)

標識接收報文的目的主機的埠或程序。

3) 序號(也叫序列號)(32位)

用於標識每個報文段,使目的主機可確認已收到指定報文段中的資料。當源主機用於多個報文段傳送一個報文時,即使這些報文到達目的主機的順序不一樣,序列號也可以使目的主機按順序排列它們。

在 SYN 標誌未置位時,該欄位指示了使用者資料區中第一個位元組的序號;在 SYN 標誌置位時,該欄位指示的是初始傳送的序列號。

在建立連線時傳送的第一個報文段中,雙方都提供一個初始序列號。TCP 標準推薦使用以 4ms 間隔遞增 1 的計數器值作為這個初始序列號的值。使用計數器可以防止連線關閉再重新連線時出現相同的序列號。

對於那些包含資料的報文段,報文段中第一個資料位元組的數量就是初始序列號,其後資料位元組按順序編號。如果源主機使用同樣的連線傳送另一個報文段,那麼這個報文段的序列號等於前一個報文段的序列號與前一個報文段中資料位元組的數量之和。例如,假設源主機發送 3 個報文段,每個報文段有 100 位元組的資料,且第一個報文段的序列號是 1000,那麼第二個報文段的序列號就是 1100(1000 + 100),第三個報文段的序列號就是 1200(1100 + 100)。

如果序列號增大至最大值將復位為 0。

4)確認號(32位)

目的主機返回確認號,使源主機知道某個或幾個報文段已被接收。如果 ACK 控制位被設定為 1,則該欄位有效。確認號等於順序接收到的最後一個報文段的序號加 1,這也是目的主機希望下次接收的報文段的序號值。返回確認號後,計算機認為已接收到小於該確認號的所有資料。

例如,序列號等於前一個報文段的序列號與前一個報文段中資料位元組的數量之和。例如,假設源主機發送 3 個報文段,每個報文段有 100 位元組的資料,且第一個報文段的序列號是 1000,那麼接收到第一個報文段後,目的主機返回含確認號1100 的報頭。接收到第二個報文段(其序號為 1100 )後,目的主機返回確認號 1200。接收到第三個報文段後,目的主機返回確認號 1300 。

目的主機不一定在每次接收到報文段後都返回確認號。在上面的例子中,目的主機可能等到所有 3 個報文段都收到後,再返回一個含確認號 1300 的報文段,表示已接收到全部 1200 位元組的資料。但是如果目的主機再發回確認號之前等待時間過長,源主機會認為資料沒有到達目的主機,並自動重發。

上面的例子中,如果目的主機接收到了報文段號為 1000 的第一個報文段以及報文段號為 1200 的最後一個報文段,則可返回確認號 1100,但是再返回確認號 1300 之前,應該等待報文段號為 1100 的中間報文段。

5) 資料偏移(首部長度)(4位)

TCP 報文段的資料起始處距離 TCP 報文段的起始處有多遠,即首部長度。由於 TCP 報頭的長度隨 TCP 選項欄位內容的不同而變化,因此報頭中包含一個指定報頭欄位的欄位。該欄位以 32 位元為單位,所以報頭長度一定是 32 位元的整數倍,有時需要在報頭末尾補 0 。如果報頭沒有 TCP 選項欄位,則報頭長度值為 5 ,表示報頭一個有 160 位元,即 20 位元組。

6)保留位(6位)

由跟在資料偏移欄位後的 6 位構成, 全部為 0 。

7)控制位(6位)

緊急 URG:此位置 1,表明緊急指標欄位有效,它告訴系統此報文段中有緊急資料,應儘快傳送。

確認 ACK:僅當 ACK = 1 時確認號欄位才有效,TCP 規定,在連線建立後所有傳達的報文段都必須把 ACK 置 1。

推送 PSH:當兩個應用程序進行互動式的通訊時,有時在一端的應用程序希望在鍵入一個命令後立即就能夠收到對方的響應。在這種情況下,TCP 就可以使用推送(push)操作,這時,傳送方 TCP 把 PSH 置 1 ,並立即建立一個報文段傳送出去,接收方收到 PSH = 1 的報文段,就儘快地(即“推送”向前)交付給接收應用程序,而不再等到整個快取都填滿後再向上交付。

復位 RST:用於復位相應的 TCP 連線

同步 SYN:僅在三次握手建立 TCP 連線時有效。當 SYN = 1 而 ACK = 0 時,表明這是一個連線請求報文段,對方若同意建立連線,則應在相應的報文段中使用 SYN = 1 和 ACK = 1。因此,SYN 置 1 就表示這是一個連線請求或連線接受報文。

終止 FIN:用來釋放一個連線。當 FIN = 1 時,表明此報文段的傳送方的資料已經發送完畢,並要求釋放運輸連線。

8)視窗(16位)

此欄位用來進行流量控制,這個值是本機期望一次接收的位元組數,即傳送資料的視窗大小。告訴對方在不等待確認的情況下,可以發來多大的資料。這裡表示的最大長度是2^16 - 1 = 65535,如需要使用更大的視窗大小,需要使用選項中的視窗擴大因子選項。

指傳送本報文段的一方的接收視窗(而不是自己的傳送視窗)。

9)校驗和(16位)

源主機和目的主機根據 TCP 報文段以及偽報頭的內容計算校驗和。在偽報頭中存放著來自 IP 報頭以及 TCP 報文段長度資訊。與 UDP 一樣,偽報頭並不在網路中傳輸,並且在校驗和中包含偽報頭的目的是為了防止目的主機錯誤地接收存在路由的錯誤資料報。

偽首部,又稱為偽包頭(Pseudo Header):是指在 TCP 的分段或 UDP 的資料報格式中,在資料報首部前面增加源 IP 地址、目的 IP 地址、IP 分組的協議欄位、TCP 或 UDP 資料報的總長度等共12位元組,所構成的擴充套件首部結構。此偽首部是一個臨時的結構,它既不向上也不向下傳遞,僅僅只是為了保證可以校驗套接字的正確性。

10)緊急指標(16位)

僅在 URG = 1 時才有意義,它指出本報文段中的緊急資料的位元組數(緊急資料結束後就是普通資料),即指出了緊急資料的末尾在報文中的位置,注意:即使視窗為零時也可傳送緊急資料。

如果 URG 為 1 ,則緊急指標標誌著緊急資料的結束。其值是緊急資料最後 1 位元組的序號,表示報文段序號的偏移量。例如,如果報文段的序號是 1000,前 8 個位元組都是緊急資料,那麼緊急指標就是 8 。緊急指標一般用途是使使用者可中止程序。

11)選項、填充欄位

可能包括“視窗擴大因子”、“時間戳”等選項。長度可變,最長可達 40 位元組,當沒有使用選項時,TCP 首部長度是 20 位元組。

填充用於保證任選項為 32bit 的整數倍。

12)資料(長度可變)

TCP 首部結束之後的部分

UDP 報文格式

UDP 是 User Datagram Protocol 的簡稱, 中文名是使用者資料報協議,是一種無連線的傳輸層協議,提供面向事務的簡單不可靠資訊傳送服務。

1)源埠(2 位元組):傳送方埠號

2)目的埠(2 位元組 ):接收方埠號

3)報文長度(2 位元組):UDP 使用者資料報的總長度(頭部+資料),以位元組為單位。

4)校驗和(2 位元組):檢測 UDP 使用者資料報在傳輸中是否有錯,有錯就丟棄。

用於校驗 UDP 資料報的數字段和包含 UDP 資料報首部的“偽首部”。

偽首部,又稱為偽包頭(Pseudo Header):是指在 TCP 的分段或 UDP 的資料報格式中,在資料報首部前面增加源 IP 地址、目的 IP 地址、IP 分組的協議欄位、TCP 或 UDP 資料報的總長度等共12位元組,所構成的擴充套件首部結構。此偽首部是一個臨時的結構,它既不向上也不向下傳遞,僅僅只是為了保證可以校驗套接字的正確性。

5)資料:UDP 的資料部分如果不為偶數需要用 0 填補,就是說,如果資料長度為奇數,資料長度加“1”。