TCP/IP

TCP 序列號 (Sequence Number, SEQ)

序列號 (Sequence Number, SEQ) 是 TCP 表頭的欄位之一,
欄位大小為 32 bits,因此其 數值範圍 為 0 ~ 232 – 1,
是 TCP 設計的根本概念,幾乎所有功能都依賴此欄位完成。
 

TCP-Header-Format (SEQ)
TCP 表頭格式
 


 

可靠性 (Reliability)

TCP 流量控制 (Flow Control) 中提過,
TCP 每次 發送 與 接收 單位為: TCP 區段 (TCP Segment)
每個區段的大小不盡相同,有可能 數百~數萬 個位元組。
encapsulation
 
就像 最大區段長度 (Maximum Segment Size, MSS)
指的是 所能接收資料』的最大長度,而非區段!
 
TCP 會為每條連線發送的 資料位元組 (octet of data) 分配 序列號,
序列號 (Sequence Number, SEQ) 欄位,
放的是該區段 資料位元組 的 第一個序列號 (除非無攜帶資料)!
(真心覺得這些命名很瞎 🙄)
 

 
TCP/IP 的網路層 — — IP 協定,不保證資料會照發送順序抵達 接收端,
接收端 可利用表頭中的 序列號 (Sequence Number, SEQ) 欄位 進行排序消除重複 (eliminate duplicates)
以保證資料接收的正確順序,並以 位元組串流 (byte-stream) 的方式,傳遞給應用層。
 
TCP 使用 確認號 (Acknowledgment Number) 欄位,
指出下一個期望接收序列號 (Sequence Number, SEQ)
(表示 編號小於此值的位元組,皆已正確接收)
 
again:

序列號 (Sequence Number, SEQ)並不是 區段的 id 或 編號 !
它不代表一個唯一的 區段,
且不同於資料庫的主鍵,其值有可能重複。

 

 


 

無攜帶資料

有些區段並不會攜帶資料,自然不存在 資料位元組。
如:

  • 建立、結束連線
  • 無攜帶資料之 確認區段

 
儘管其值無效,該 區段 仍需使用一個 序列號 (Sequence Number, SEQ)
 
 

初始序列號 (Initial Sequence Number, ISN)

為了避免與先前連線的區段混淆,
當次連線建立時,序列號 並非從 0 開始,
兩端會使用 ISN 產生器,產生各自的 初始序列號 (Initial Sequence Number, ISN)
通常兩者並不相等,且如本篇開頭所述,數值範圍 為 0 ~ 232 – 1。
 
連線建立時,透過 控制位元 (Control Bits) 中的 SYN
讓兩端的 TCP 必須進行 ISN 的交換 (同步),

 

SYN 全名 同步序列號 (Synchronize sequence numbers)
使用 SYN,代表目前區段的 序列號 為 初始序列號,
而非 資料位元組 的第一個序列號。

 
Synchronize-sequence-numbers
 
這就是 TCP 連線的建立方式,
且 2 和 3,可以組合為單一訊息,
即大名鼎鼎的 — — TCP 三向交握 (Three Way Handshake)
 
Ex:

而 第三個區段 (Client — — > Server),
其 SEQ 為 第一個區段的值 + 1 (ISN + 1)。
 
 

相對序列號 (Relative Sequence Number)

如果你有用 Wireshark 之類的封包分析軟體,
可能會以為我爪你: 「ISN 就是 0 啊,根本不是亂數 🙄」。

 
那不是真的 SEQ,而是相對 SEQ!
真正的值可能很大很難看,
為了方便觀察,大部分工具都會提供相對 SEQ。
(將 ISN 做為基底值)
 
要取消可以按右鍵設定:

 
接著,就可以看到很鏘的數:

 
 

無攜帶資料之 確認區段

大部分 TCP 實作,對 無攜帶資料 之 確認 (ACK) 區段
視為 序列號無效,並且 不消耗任何序列號。
 
也就是:

序列號 (SEQ) 將重複使用,直到區段攜帶資料。

 

範例

承上述範例,第三個區段 (Client — — > Server) 的 SEQ 為 101 (此時連線建立完成),
第四個區段,送出 攜帶資料的 區段 (Client — — > Server),
SEQ 將同樣為 101,而非 102 (101 + 1)。
(因為第三個區段 是 無攜帶資料之 確認區段,序列號將重複使用)

 
別忘記了,區段長度 (Segment Len) 是個腦殘的命名,
指的是 資料長度,而非區段。
 
Segment Len: 999 代表「含序列號 101 的資料,共有 999 個資料位元組」,
(101、102、103、…、…、1098、1099)

 
假設成功送達 Server,且區段沒有毀損,
第五個區段 確認號 (Acknowledgment Number) 將設為 1100
(表示編號小於 1100 的位元組,皆已正確接收)
 
第六 與 第七個區段 (Client < — — Server),Server 送出攜帶 1440 (位元組) 資料的 區段,
由於尚未收到 Client 回覆,「期望收到的 序列號」 = 確認號 (ACK Number),與第五個區段 一樣為 1100

 
第八個區段 (Client — — > Server),
一樣是 無攜帶資料之 確認區段 區段。
 
因此,如果有 第九個區段 (Client < — — Server) (懶得畫了😂),
Server 之 確認號 (ACK Number) 將一樣為 1100
 
第十個區段 (Client — — > Server),
Client 之 序列號,也將維持 1100 不變,直到其攜帶資料。
 

無攜帶資料之 確認區段
其 序列號 (SEQ) 將 重複使用,直到區段攜帶資料 或 拆除連線。

 
 

作者: 鄭中勝
喜愛音樂,但不知為何總在打程式 ? 期許能重新審視、整理自身所學,幫助有需要的人。

在《TCP 序列號 (Sequence Number, SEQ)》中有 6 則留言

  1. 文章寫得太好了,非常讚賞。但我有些問題請教:

    step 6 的 1440 從何來?
    以及是否 handshake 的頭三個step 才加1?

  2. 文章寫得太好了,非常讚賞。但我有些問題請教:

    step 6 的 1440 從何來?
    以及是否 handshake 的頭三個step 才加1?

  3. 請問為什麼 第六區段 client 會沒有回覆,需要再送第七區段?
    是指例外情況,比如資料遺失或等待client ACK time out?

    1. 還是說 傳接資料不一定是一端發了另一端就要馬上送? 一端可以一次發送好幾筆TCP Segments,彼端只需要一次ACK?

發表迴響