網絡小故事 15 · 進階

小比平安到達了嗎?TCP 的 Sequence Number(序號)與 ACK(確認)

一張相片被切成很多個封包,少了一個怎麼辦?

主角:小比、阿麥閱讀時間約 10 分鐘

建議先讀:第 9 課

1. 故事

按「下一步」一步一步看。每一步都有一位角色出場,解釋自己正在做什麼。

序幕:溫習一下

第 1 步/共 13 步

先握手

用 TCP(傳輸控制協定)傳資料之前,雙方先做 Three-way Handshake(三次握手):SYN「你好?」、SYN-ACK「你好!」、ACK「開始吧!」

動畫文字版(全部步驟)
  1. 序幕:溫習一下
  2. 先握手 小比:用 TCP(傳輸控制協定)傳資料之前,雙方先做 Three-way Handshake(三次握手):SYN「你好?」、SYN-ACK「你好!」、ACK「開始吧!」
    • 握手時,雙方也交換了各自的起始序號
    • 詳細內容:第 9 課
  3. IP 只會盡力送 阿麥:我要下載一張相片。可是互聯網上的 Router(路由器)只會「盡力而為」:太忙時可能丟掉封包,也不保證次序。相片少了一塊就會變成爛圖,怎麼辦?
    • IP:負責找路,不保證送到、不保證次序
    • TCP:在兩端補上「一定送到、按次序」
  4. 第一幕:每份都有編號
  5. 切開、編號 小比:伺服器把 6,000 Byte 的相片切成 6 份,每份 1,000 Byte。每份背包上都寫著 Sequence Number(序號):它由第幾個 Byte 開始。
    • 第 1 份:Seq 1(第 1 至 1,000 Byte)
    • 第 2 份:Seq 1001
    • 第 3 份:Seq 2001
    • 第 4 份:Seq 3001
    • 第 5、6 份:Seq 4001、5001
    • 真實的起始序號是隨機的,這裡用「相對序號」,由 1 開始
  6. 送出第 1 份 小比:我背著 Seq 1 出發,平安到達阿麥那裡!
  7. ACK:下一個想要的號碼 阿麥:我收到 1 至 1,000 Byte,於是回覆 ACK 1001。意思是:「1001 之前的全部收到,下一份請由 1001 開始。」
    • ACK(確認)= 下一個想要的 Byte 號碼
    • 它是累積的:ACK 1001 代表 1001 之前全部收到
  8. 一次送出幾份 小比:每份都等 ACK 太慢了!伺服器可以一次送出好幾份,才一起等 ACK。Seq 1001 至 5001 一齊出發!
    • 可以同時「在路上」而未確認的資料量,叫 Window(窗口)
  9. 第二幕:有一個小比走失了
  10. Seq 2001 不見了! 小比:糟糕!互聯網上一部 Router 太忙,把背著 Seq 2001 的小比丟掉了。其他小比則平安到達。
  11. 阿麥一直催:ACK 2001 阿麥:我收到 1001,回覆 ACK 2001。接著收到 3001、4001、5001,但 2001 還未到!我先把它們放在一旁,每收到一份,都再次回覆 ACK 2001:「我還在等 2001!」
    • 第一個 ACK 2001:收到 1001 後的正常回覆
    • 之後三個:收到 3001、4001、5001 時的 Duplicate ACK(重複確認)
  12. 重送走失的一份 小比:伺服器連續收到 3 個重複的 ACK 2001,就知道 2001 走失了,立即重送一次,這叫 Retransmission(重傳)。如果連 ACK 都收不到,伺服器也會等計時器到期再重送。
    • 收到 3 個重複 ACK 就立即重送:Fast Retransmit(快速重傳)
    • 計時器到期才重送:逾時重傳
  13. 全部收齊:ACK 6001 阿麥:2001 補回來了!加上一直放在一旁的幾份,6,000 Byte 全部收齊。我一次回覆 ACK 6001,再按序號把六份排好,相片完整無缺!
  14. 第三幕:控制速度與道別
  15. 別送得太快 阿麥:我每個 ACK 都會附上「我還有多少空位」,叫 Window。空位不夠,伺服器就要慢下來,這是 Flow Control(流量控制)。伺服器發現有小比走失,也會當網絡塞車而減速,這是 Congestion Control(擁塞控制)。
  16. 說再見:FIN 小比:傳送完畢,雙方各自送出 FIN「再見!」,並由對方用 ACK 確認。這次 TCP 對話正式結束。
  17. 總結:平安到達 小比:序號標明每份的位置,ACK 告訴寄件人收到哪裡;走失了就重送,次序亂了就重新排好。有了 TCP,網頁、電郵和檔案都可以完整無缺地送到!
    • Sequence Number:這份由第幾個 Byte 開始
    • ACK:下一個想要的號碼(累積確認)
    • 走失 → 重複 ACK 或逾時 → Retransmission

2. 問題在哪裡

互聯網上的 Router(路由器)只負責找路。它們遵守的是 IP(互聯網協定),即按 IP Address(網絡位址)把 Packet(封包)一站一站送出去的規則。IP 標頭還有 TTL(存活時間),每經過一部 Router 減 1,防止封包永遠兜圈。IP 的承諾只是「盡力而為」:

  • 可能遺失:Router 太忙、隊伍太長時,會直接丟掉封包,不會通知任何人。
  • 可能亂序:不同封包可能走不同的路,後出發的反而先到。
  • 可能重複:同一份資料有時會送到兩次。

一張 6,000 Byte(位元組)的相片,被切成 6 個小比上路。只要少了一份,或者次序排錯,阿麥看到的就是一張爛圖。

3. 網絡怎樣解決

想像你寄一套六冊的漫畫給朋友,每個包裹都寫上「第幾頁開始」。朋友收到後,就回條說「下一本請由第幾頁開始」。哪一本沒回條,你就再寄一次。

TCP(傳輸控制協定)就是這樣做:在兩端的電腦為資料編上 Sequence Number(序號),收件人用 ACK(確認)回覆「下一個想要的號碼」。走失了就重送,次序亂了就重新排好。

沿途的 Router 完全不用理會這些,一切由兩端負責。

4. 看深一點

Sequence Number 數的是 Byte,不是份數

Sequence Number 表示「這份資料的第一個 Byte,是整段資料的第幾個 Byte」。故事中伺服器 example.com(192.0.2.80:443)把相片切成每份 1,000 Byte。(留意:192 開頭不一定是 Private,只有 192.168 開頭才是。)

份數 Sequence Number 包含的 Byte
第 1 份 1 1 – 1,000
第 2 份 1001 1,001 – 2,000
第 3 份 2001 2,001 – 3,000
第 4 份 3001 3,001 – 4,000
第 5 份 4001 4,001 – 5,000
第 6 份 5001 5,001 – 6,000

真實的起始序號在 Three-way Handshake(三次握手)時隨機選出,例如 2837461005。Wireshark 等工具會換算成由 1 開始的「相對序號」,方便閱讀,故事也用這個方法。

ACK = 下一個想要的 Byte 號碼

阿麥收到第 1 至 1,000 Byte,就回覆 ACK 1001,意思是「1001 之前全部收到,請由 1001 繼續」。

ACK 是累積的:ACK 6001 代表第 1 至 6,000 Byte 全部收齊,不用逐份回覆。

Window(窗口):一次送出幾份

如果每送一份都要停下來等 ACK,一來一回的時間就全浪費了。所以伺服器可以一次送出好幾份,才一起等 ACK。

可以同時「在路上」而未確認的資料量,叫 Window。

走失了怎樣發現?

故事中 Seq 2001 在互聯網上被丟掉了,阿麥收到的是這樣:

收到          阿麥回覆
Seq 1001  →  ACK 2001
(2001 走失)
Seq 3001  →  ACK 2001(重複)
Seq 4001  →  ACK 2001(重複)
Seq 5001  →  ACK 2001(重複)
重送 2001 →  ACK 6001

阿麥把 3001、4001、5001 暫時放在 Buffer(緩衝區),不會丟掉。伺服器發現有兩種方法:

  1. Fast Retransmit(快速重傳):連續收到 3 個 Duplicate ACK(重複確認),立即重送 2001,不用等。
  2. 逾時重傳:送出資料後會開一個計時器,到期仍收不到 ACK,就重送。如果連 ACK 都在路上走失,就靠這個方法。

兩者都屬於 Retransmission(重傳)。補回 2001 後,阿麥一次回覆 ACK 6001,再按序號把六份排好。

Flow Control(流量控制)與 Congestion Control(擁塞控制)

  • Flow Control:阿麥每個 ACK 都附上「我還有多少空位」,例如 ACK 6001|Window 8000。空位不夠,伺服器就要慢下來,免得塞爆阿麥。
  • Congestion Control:伺服器發現資料走失,會估計是網絡塞車,於是自動減少一次送出的份量,之後再慢慢加快。

所以,一次可以送多少,由兩者之中較小的一個決定。

說再見:FIN

傳送完畢,雙方各自送出 FIN「再見!」,對方用 ACK 確認。因為兩個方向要各自關閉,所以通常一共有四個訊息:FIN、ACK、FIN、ACK。

5. 動手試試

任務:看看重傳有多常見

  1. 在電腦打開「命令提示字元」(Windows)或「終端機」(macOS/Linux)。
  2. Windows 輸入 netstat -s;macOS 輸入 netstat -s -p tcp。
  3. 在一大堆統計數字中,找找有 retransmit 或「重新傳送」字眼的一行。
  4. 和已送出的數目比一比,你會發現重傳雖然不多,但一直都在發生。TCP 每天都在默默替你補回走失的小比!

小互動

誰負責?

以下六項工作,由 TCP(兩端的電腦)還是 IP(沿途的 Router)負責?

  1. 1把資料切成多份並編上序號

  2. 2按 IP Address 把 Packet 一站一站送到目的地

  3. 3發現資料走失並重送

  4. 4用 TTL 防止 Packet 永遠兜圈

  5. 5在收件人那邊按次序排好資料

  6. 6用 Window 控制寄件速度

6. 比喻的極限

  • 每份不一定是 1,000 Byte。 真實的大小受 MTU(最大傳輸單位)影響,Ethernet(以太網)上每份最多約 1,460 Byte 資料;故事用 1,000 只是為了容易計算。
  • ACK 不一定每份回一次。 很多電腦會等收到兩份才回一個 ACK,或者把 ACK 夾在自己要送的資料裡一起送出,這樣更省。
  • 序號不是由 1 開始。 真實的起始序號是隨機的大數字,一來防止舊連線的資料混進來,二來令別人較難偽造封包。
  • TCP 保證的是「送到」,不是「保密」。 TCP 不會加密內容;要防止別人偷看,需要 TLS(傳輸層安全),下兩個故事會講。
  • 重送不是無限次。 重送多次仍然失敗,TCP 就會放棄並中斷連線,這時你會看到「連線逾時」之類的錯誤。

7. 小測驗

第 1 題,共 3 題阿麥收到 Seq 1、長度 1,000 Byte 的資料,他會回覆什麼?
第 2 題,共 3 題Seq 2001 走失了,阿麥之後收到 Seq 3001,他會怎樣做?
第 3 題,共 3 題為什麼 TCP 可以一次送出好幾份資料,才等 ACK?

8. 重點筆記

  • IP 只會盡力送,封包可能遺失、亂序或重複;TCP(傳輸控制協定)在兩端補上「一定送到、按次序」。
  • Sequence Number(序號)數的是 Byte:表示這份資料由第幾個 Byte 開始。
  • ACK(確認)= 下一個想要的 Byte 號碼,而且是累積的。
  • 走失的資料靠 Retransmission(重傳)補回:收到 3 個 Duplicate ACK 就快速重傳,或等計時器到期再重傳。
  • Window 讓伺服器一次送出幾份;Flow Control 保護收件人,Congestion Control 保護網絡。

延伸閱讀

有了序號和 ACK,小比就算走失也會被補回來,相片完整無缺。可是,萬一不是走失,而是整條路都不通呢?下一個故事,路路會變身網絡醫生,用 Ping 和 Traceroute 找出問題出在哪一站。