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 中的流水號是 ,就表示「流水號嚴格小於 的 byte 都有收到」,或者是說「下一個期待收到的位元是 」。
原則二:收到封包一定要 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 →
在這個情況中:
- 接收方收到收到
(seq=70, len=20)
的封包。
- 接收方回覆
ACK=90
。
- 接收方的
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 →
- 發送方依序傳送
(seq=70, len=20)
跟 (seq=90, len=10)
的封包。
- 接收方確實收到這兩個封包,並且依序回傳
ACK=90
與 ACK=100
。
ACK=100
的封包先到,但是 ACK=90
的封包遺失。
這時候,因為採用 cumilated ACK,所以發送方一但看到 ACK=100
,就知道「流水號嚴格小於 100
的那些位元組都收到了」,而這也包含流水號 70
到 89
的位元組。因此,即使沒有收到 (seq=70, len=20)
封包的 ACK=90
,只要收到 ACK=100
,發送方也可以知道 (seq=70, len=20)
已經順利送達,所以就不需要重傳。
情境三:Delayed ACK
ACK 除了可能少之外,也有可能多。比如說接收方雖然有發送了 ACK,但來不及在原先的 Timeout 前抵達,因此在下一個 timeout 時間區間內抵達的時候。這時候在發送方看來,就會像是「莫名其妙多出了很多個 ACK」。比如說這個情境:
- 發送方依序傳送
(seq=70, len=20)
跟 (seq=90, len=10)
的封包。
- 接收方確實收到這兩個封包,並且依序回傳
ACK=90
與 ACK=100
。
- 這兩個 ACK 太慢,沒有在時間內送達。
- 因為沒有在時間內送達,所以發送方重新發送。第一個封包是
(seq=70, len=20)
的封包。
- 重傳的
(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 時:
- 因為接收方已經已經收到
(seq=70, len=20)
與 (seq=90, len=10)
封包了,所以接下來預期會收到 seq=100
的封包。因此在這個 ACK 當中,就要回覆 ACK=100
。
- (在這個情境中) 假定
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 ~ 5。
- 只有流水號為 2 封包沒有送達,而其他封包都送達了。
這時,依照前面的傳輸原則:每收到一個封包,都一定要 ACK 下一個期待收到的流水號(在這個例子中,就是一直沒收到的 2 號封包)。所以:
- 在收到編號 3、4、5 的封包時,接收方都會回
ACK=2
。
- 如果這時發送方什麼都沒做,那麼就要一直到逾時之後,才會發現流水號 2 的封包沒有送達。因此就需要在逾時之後重送。
- 接收方收到重送之後,因為流水號 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 →