TCP重傳, 滑動窗口, 流量控制, 擁塞控制
1. 重傳機制
TCP 實現(xiàn)可靠傳輸?shù)姆绞街?,是通過序列號與確認應(yīng)答。
在 TCP 中,當發(fā)送端的數(shù)據(jù)到達接收主機時,接收端主機會返回一個確認應(yīng)答消息,表示已收到消息。
針對數(shù)據(jù)可能丟失的情況, 用重傳機制來解決, 四種常見的重傳機制:
- 超時重傳
- 快速重傳
- SACK
- D-SACK
1.1 超時重傳
在發(fā)送數(shù)據(jù)時,設(shè)定一個定時器,當超過指定的時間后,沒有收到對方的 ACK
確認應(yīng)答報文,就會重發(fā)該數(shù)據(jù),也就是我們常說的超時重傳。
分為兩種:
- 數(shù)據(jù)包丟失
- 確認應(yīng)答丟失
超時時間:
RTT(Round-Trip Time 往返時延): 數(shù)據(jù)發(fā)送時刻到接收到確認的時刻的差值
RTO(Retransmission Timeout 超時重傳時間)
超時重傳時間 RTO 的值應(yīng)該略大于報文往返 RTT 的值。
實際上「報文往返 RTT 的值」是經(jīng)常變化的,因為我們的網(wǎng)絡(luò)也是時常變化的。也就因為「報文往返 RTT 的值」 是經(jīng)常波動變化的,所以「超時重傳時間 RTO 的值」應(yīng)該是一個動態(tài)變化的值。
實際中, 每當遇到一次超時重傳的時候,都會將下一次超時時間間隔設(shè)為先前值的兩倍。兩次超時,就說明網(wǎng)絡(luò)環(huán)境差,不宜頻繁反復(fù)發(fā)送。
1.2 快讀重傳
不以時間為驅(qū)動,而是以數(shù)據(jù)驅(qū)動重傳
在上圖,發(fā)送方發(fā)出了 1,2,3,4,5 份數(shù)據(jù):
- 第一份 Seq1 先送到了,于是就 Ack 回 2;
- 結(jié)果 Seq2 因為某些原因沒收到,Seq3 到達了,于是還是 Ack 回 2;
- 后面的 Seq4 和 Seq5 都到了,但還是 Ack 回 2,因為 Seq2 還是沒有收到;
- 發(fā)送端收到了三個 Ack = 2 的確認,知道了 Seq2 還沒有收到,就會在定時器過期之前,重傳丟失的 Seq2。
- 最后,收到了 Seq2,此時因為 Seq3,Seq4,Seq5 都收到了,于是 Ack 回 6 。
快速重傳的工作方式是當收到三個相同的 ACK 報文時,會在定時器過期之前,重傳丟失的報文段。
快速重傳機制只解決了一個問題,就是超時時間的問題,但是它依然面臨著另外一個問題。就是重傳的時候,是重傳一個,還是重傳所有的問題。
1.3 SACK方法
實現(xiàn)重傳機制的方式叫:SACK
( Selective Acknowledgment), 選擇性確認。
這種方式需要在 TCP 頭部「選項」字段里加一個 SACK
的東西,它可以將已收到的數(shù)據(jù)的信息發(fā)送給「發(fā)送方」,這樣發(fā)送方就可以知道哪些數(shù)據(jù)收到了,哪些數(shù)據(jù)沒收到,知道了這些信息,就可以只重傳丟失的數(shù)據(jù)。
如下圖,發(fā)送方收到了三次同樣的 ACK 確認報文,于是就會觸發(fā)快速重發(fā)機制,通過 SACK
信息發(fā)現(xiàn)只有 200~299
這段數(shù)據(jù)丟失,則重發(fā)時,就只選擇了這個 TCP 段進行重復(fù)。
1.4 Duplicate SACK
主要使用了 SACK 來告訴「發(fā)送方」有哪些數(shù)據(jù)被重復(fù)接收了。
分為ACK丟包和網(wǎng)絡(luò)延時
2. 滑動窗口
流量控制可以讓發(fā)送端根據(jù)接收端的實際接受能力控制發(fā)送的數(shù)據(jù)量。它的具體操作是,接收端主機向發(fā)送端主機通知自己可以接收數(shù)據(jù)的大小,于是發(fā)送端會發(fā)送不會超過該大小的數(shù)據(jù),該限制大小即為窗口大小,即窗口大小由接收端主機決定。
TCP 首部中,專門有一個字段來通知窗口大小,接收主機將自己可以接收的緩沖區(qū)大小放在該字段中通知發(fā)送端。當接收端的緩沖區(qū)面臨數(shù)據(jù)溢出時,窗口大小的值也是隨之改變,設(shè)置為一個更小的值通知發(fā)送端,從而控制數(shù)據(jù)的發(fā)送量,這樣達到流量的控制。這個控制流程的窗口也可以稱作滑動窗口。
3. 流量控制
左邊發(fā)送端, 右邊接收端, 白色空余位置, 粉色有數(shù)據(jù)但是未發(fā)送(為讀到內(nèi)存中), 灰色已發(fā)送
從三次握手 -> 數(shù)據(jù)通信 -> 四次揮手全過程:
# fast sender: 客戶端
# slow recerver: 服務(wù)器
# win: 滑動窗口大小
# mss: maximum segment size, 單條數(shù)據(jù)的最大長度
第4~9步: 客戶端給服務(wù)器發(fā)送數(shù)據(jù)
- 1(1024):1 (1-0)表示之前一共給服務(wù)器發(fā)送了1個字節(jié),(1024)表示這次要發(fā)送的數(shù)據(jù)量為 1k
- 1025(1024):1025(1025-0)表示之前一共給服務(wù)器發(fā)送了1025個字節(jié),(1024)表示這次要發(fā)送的數(shù)據(jù)量為 1k
第10步:
-
ack6145: 服務(wù)器給客戶端回復(fù)數(shù)據(jù),6145是確認序號, 代表實際接收的字節(jié)數(shù)
服務(wù)器實際接收的字節(jié)數(shù) = 確認序號 - 客戶端生成的隨機序號 ===> 6145 = 6145 - 0
-
win2048:服務(wù)器告訴客戶端我的緩存還有2k,也就是還有4k還在緩存中沒有被讀走
第11步:win4096表示滑動窗口變?yōu)?k,代表還可以接收4k數(shù)據(jù),還有2k在緩存中
第12步:客戶端又給服務(wù)器發(fā)送了1k數(shù)據(jù)
第13步: 第一次揮手,F(xiàn)IN表示客戶端主動和服務(wù)器斷開連接,并且發(fā)送了1k數(shù)據(jù)到服務(wù)器端
第14步: 第二次揮手,回復(fù)ACK, 同意斷開連接
第15, 16步: 服務(wù)器端從讀緩沖區(qū)中讀數(shù)據(jù), 第16步數(shù)據(jù)讀完, 滑動窗口變成最大的6k
第17步:
- FIN: 服務(wù)器請求和客戶端斷開連接
- 8001(0): 服務(wù)器一共給客戶端發(fā)送的字節(jié)數(shù) 8001 - 8000 = 1個字節(jié),攜帶的數(shù)據(jù)量為0(FIN不計算在內(nèi))
- ack8194: 服務(wù)器收到了客戶端的多少個字節(jié): 8194 - 0 = 8194個字節(jié)
第18步: 第四次揮手
- ACK: 客戶端同意了服務(wù)器斷開連接的請求
- 8002: 確認序號, 可以計算出服務(wù)器給客戶端發(fā)送了多少數(shù)據(jù),8002 - 8000 = 2 個字節(jié)
4. 擁塞控制
在網(wǎng)絡(luò)出現(xiàn)擁堵時,如果繼續(xù)發(fā)送大量數(shù)據(jù)包,可能會導(dǎo)致數(shù)據(jù)包時延、丟失等,這時 TCP 就會重傳數(shù)據(jù),但是一重傳就會導(dǎo)致網(wǎng)絡(luò)的負擔(dān)更重,于是會導(dǎo)致更大的延遲以及更多的丟包,這個情況就會進入惡性循環(huán)被不斷地放大…
所以,TCP 不能忽略網(wǎng)絡(luò)上發(fā)生的事,它被設(shè)計成一個無私的協(xié)議,當網(wǎng)絡(luò)發(fā)送擁塞時,TCP 會自我犧牲,降低發(fā)送的數(shù)據(jù)量。
于是,就有了擁塞控制,控制的目的就是避免「發(fā)送方」的數(shù)據(jù)填滿整個網(wǎng)絡(luò)。
為了在「發(fā)送方」調(diào)節(jié)所要發(fā)送數(shù)據(jù)的量,定義了一個叫做「擁塞窗口」的概念。
擁塞窗口 cwnd是發(fā)送方維護的一個的狀態(tài)變量,它會根據(jù)網(wǎng)絡(luò)的擁塞程度動態(tài)變化的。
我們在前面提到過發(fā)送窗口 swnd
和接收窗口 rwnd
是約等于的關(guān)系,那么由于加入了擁塞窗口的概念后,此時發(fā)送窗口的值是swnd = min(cwnd, rwnd)
,也就是擁塞窗口和接收窗口中的最小值。
擁塞窗口 cwnd
變化的規(guī)則:文章來源:http://www.zghlxwxcb.cn/news/detail-815871.html
- 只要網(wǎng)絡(luò)中沒有出現(xiàn)擁塞,
cwnd
就會增大; - 但網(wǎng)絡(luò)中出現(xiàn)了擁塞,
cwnd
就減少;
其實只要「發(fā)送方」沒有在規(guī)定時間內(nèi)接收到 ACK 應(yīng)答報文,也就是發(fā)生了超時重傳,就會認為網(wǎng)絡(luò)出現(xiàn)了擁塞。文章來源地址http://www.zghlxwxcb.cn/news/detail-815871.html
到了這里,關(guān)于TCP重傳, 滑動窗口, 流量控制, 擁塞控制的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!