Try   HackMD

TCP - Retransmission

這篇文章中簡介幾個 TCP 重傳的情境。

課程影片

第 8G 講 TCP 與網路阻塞偵測與控制技術 L08 7

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

How TCP Works - Duplicate Acknowledgments

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

前情提要:TCP 的 ACK 機制

原則一:ACK 的流水號 = 預計收到的下個位元組的流水號

TCP 以 byte 為單位,使用 cumilated ACK。也就是說:若接收方回覆的 ACK 中的流水號是

n,就表示「流水號嚴格小於
n
byte 都有收到」,或者是說「下一個期待收到的位元是
n
」。

原則二:收到封包一定要 ACK

除了這之外,只要收到封包,就一定要 ACK - 就算已經收過這個封包也一樣。而不管是哪一個情境,收到封包要回的 ACK 一定是依照上一個原則,回覆「預計下一個收到的位元組的流水號」。

幾種重傳情境

情境一:Lost ACK

一個罪名線的狀況是:在時限結束前都沒有收到那個封包的 ACK。一個可能的情境像這樣:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

在這個情況中:

  1. 接收方收到收到 (seq=70, len=20) 的封包。
  2. 接收方回覆 ACK=90
  3. 接收方的 ACK=90 封包遺失。

接下來,因為傳輸方沒有收到 ACK=90,所以把 (seq=70, len=20) 的封包重新傳輸。接收方在收到之後,回覆 ACK=90

情境二:Cumilated ACK

不過,遺失 ACK 不一定表示需要重傳。這是因為 TCP 採用 cumilated ACK,ACK 某個封包時,其實就是在 ACK 所有前面的封包。所以即使前面有 ACK 封包遺失,只要後面的 ACK 有送到,那麼這個後到的 ACK 就足以讓發送方知道前面的封包已經送達。比如說以下的情境:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  1. 發送方依序傳送 (seq=70, len=20)(seq=90, len=10) 的封包。
  2. 接收方確實收到這兩個封包,並且依序回傳 ACK=90ACK=100
  3. ACK=100 的封包先到,但是 ACK=90 的封包遺失。

這時候,因為採用 cumilated ACK,所以發送方一但看到 ACK=100 ,就知道「流水號嚴格小於 100 的那些位元組都收到了」,而這也包含流水號 7089 的位元組。因此,即使沒有收到 (seq=70, len=20) 封包的 ACK=90,只要收到 ACK=100,發送方也可以知道 (seq=70, len=20) 已經順利送達,所以就不需要重傳。

情境三:Delayed ACK

ACK 除了可能少之外,也有可能多。比如說接收方雖然有發送了 ACK,但來不及在原先的 Timeout 前抵達,因此在下一個 timeout 時間區間內抵達的時候。這時候在發送方看來,就會像是「莫名其妙多出了很多個 ACK」。比如說這個情境:

  1. 發送方依序傳送 (seq=70, len=20)(seq=90, len=10) 的封包。
  2. 接收方確實收到這兩個封包,並且依序回傳 ACK=90ACK=100
  3. 這兩個 ACK 太慢,沒有在時間內送達。
  4. 因為沒有在時間內送達,所以發送方重新發送。第一個封包是 (seq=70, len=20) 的封包。
  5. 重傳的 (seq=70, len=20) 順利送達。因為「收到封包一定要 ACK」,就算這個封包的內容已經收過。所以接收方準備 ACK:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

這個狀況可以使用 cumilated ACK 化解。在接收方收到重複的封包準備 ACK 時:

  1. 因為接收方已經已經收到 (seq=70, len=20)(seq=90, len=10) 封包了,所以接下來預期會收到 seq=100 的封包。因此在這個 ACK 當中,就要回覆 ACK=100
  2. (在這個情境中) 假定 ACK=100 被發送方收到。這時因為採用 cumilated ACK,所以即時前面的 ACK=90 與第一次的 ACK=100 通通遺失,只要第二個 ACK=100 有確實收到,就可以當作流水號比 100 小的位元組都有順利收到。

情境四:Duplicated ACK

如果有一個流水號的封包一直沒收到,那接收方就會一直在 ACK 裡面的流水號說「它期待收到的那個封包」的流水號 - 就算更後面的封包已經送達。像下面這樣:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

在這個例子中,在一次 timeout 裡面,傳送了 5 個封包。其中:

  1. 每個封包都傳 1 個位元組,因此流水號各自是 1 ~ 5。
  2. 只有流水號為 2 封包沒有送達,而其他封包都送達了。

這時,依照前面的傳輸原則:每收到一個封包,都一定要 ACK 下一個期待收到的流水號(在這個例子中,就是一直沒收到的 2 號封包)。所以:

  1. 在收到編號 3、4、5 的封包時,接收方都會回 ACK=2
  2. 如果這時發送方什麼都沒做,那麼就要一直到逾時之後,才會發現流水號 2 的封包沒有送達。因此就需要在逾時之後重送。
  3. 接收方收到重送之後,因為流水號 1 ~ 5 的封包都收齊了,所以接收方期待下一個收到的封包具有流水號 6。因此回覆 ACK=6

Fast Retransmission

在上面的例子中,可以發現:如果發送方發現自己收到非常多重複的 ACK,那就表示那個流水號的封包可能一直沒有收到。既然接收方都喊這麼多次沒收到同樣的封包了,不如就直接在逾時之前重送這個封包,不用等逾時後才重送。

因此,在 TCP 當中,如果在逾時之前,就發現某一個流水號的 ACK 重複了 3 次,那麼就連逾時都不等,直接補送一份過去。

Wireshark Tips

Patterns in TCP Retransmissions (SF18US)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Going down the retransmission hole (SF20V)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →