TCP往返时延的估计和超时
一、估計往返時間
TCP與之前文章提到的rdt一樣,都采用超時/重傳機(jī)制來處理報文段的丟失問題。那么這時就會有一個新的問題:如何設(shè)置TCP超時值呢?
答案肯定是超時間隔必須大于該連接的往返時間(RTT)。但是RTT是變化的。如果超時間隔設(shè)置太短會造成不成熟的超時,這就會導(dǎo)致不必要的重傳。而時間間隔太長則對數(shù)據(jù)段丟失響應(yīng)慢。
既然RTT是變化的,那么問題又來了,如何估計RTT呢:
樣本RTT:測量從報文段發(fā)送到收到確認(rèn)的時間,這里不考慮重傳的報文段即不為重傳的報文段計算樣本RTT。
注意:在任意時刻,僅為一個已發(fā)送的但目前尚未被確認(rèn)的報文段估計樣本RTT,從而產(chǎn)生一個接近于每個RTT的新樣本RTT值。也就是隨機(jī)抽取一個當(dāng)作樣本值。
但是RTT變化,RTT樣本值也會隨之變化,因此需要一個樣本RTT均值,對收到的樣本RTT根據(jù)以下公式進(jìn)行均值處理:
樣本RTT均值=(1-a)?*?樣本RTT均值+a?*?樣本均值。
上述均值計算被稱為:指數(shù)加權(quán)移動平均,典型的:a=0.125。
下圖為RTT樣本和RTT估計:
二、設(shè)置和管理重傳超時間隔
在開口我們就提到,超時間隔要大于樣本RTT均值,但又不能大太多。因此超時間隔=樣本RTT均值+安全余量。當(dāng)樣本RTT波動大時,安全余量大些,當(dāng)波動較小時,安全余量小些。
那這個安全余量怎么算呢?
我們先看樣本RTT偏離了樣本RTT均值多少:
DevRTT=(1-b)?*?DevRTT+b?*?|樣本RTT-樣本RTT均值|。
典型的取b=0.25。
然后設(shè)置超時時間間隔:
超時時間間隔=樣本RTT均值+4?*?DevRTT。
推薦初始的超時時間間隔為1秒。當(dāng)?shù)谝粋€樣本RTT獲得后:(1)樣本RTT均值=樣本RTT
(2)DevRTT=樣本RTT/2
(3)超時時間間隔=樣本RTT均值+max(G,K?*?DevRTT)。這里K=4,G是用戶設(shè)置的時間粒度。
當(dāng)出現(xiàn)超時后,超時時間間隔的值將加倍,以免即將被確認(rèn)的后繼報文段過早出現(xiàn)超時。一旦報文段收到并更新樣本RTT均值后,超時時間間隔就又會使用上述公式計算。
三、可靠數(shù)據(jù)傳輸
TCP在IP不可靠服務(wù)之上創(chuàng)建rdt即可靠數(shù)據(jù)傳輸服務(wù)。
采取的方法主要有:
(1)流水線技術(shù)處理報文段。
(2)采用累計確認(rèn)機(jī)制。
(3)TCP使用單個重發(fā)定時器。
(4)超時事件和重復(fù)確認(rèn)都會觸發(fā)重發(fā)。
TCP發(fā)送方做的事件主要有如下:
(1)從應(yīng)用程序接收數(shù)據(jù):將數(shù)據(jù)封裝在一個報文段中,并把該報文段交給IP。每一個報文段都包含一個序號,序號是數(shù)據(jù)段中第一個數(shù)據(jù)字節(jié)在字節(jié)流中的位置編號;如果沒有啟動定時器則啟動定時器;設(shè)置超時間隔。
(2)超時:重發(fā)導(dǎo)致超時的數(shù)據(jù)段;重新開啟定時器。
(3)收到確認(rèn):來自接收方確認(rèn)報文段的到答,如果確認(rèn)了還沒有確認(rèn)的數(shù)據(jù)段,則更新還沒有確認(rèn)的狀態(tài);若還有未完成的數(shù)據(jù)段,那么重新開始定時器。
下圖是一個簡化的TCP發(fā)送方:
上圖中最后一個事件是一個來自接收方的確認(rèn)報文段的到達(dá),當(dāng)該事件發(fā)生時,TCP將ACK的值y與它的變量SendBase進(jìn)行比較。TCP狀態(tài)變量SendBase是最早未被確認(rèn)的字節(jié)的序號。TCP采用累計確認(rèn),所以y確認(rèn)了字節(jié)編號在y之前的所有字節(jié)都已經(jīng)收到。如果y>SendBase,則該ACK是在確認(rèn)一個或多個先前未被確認(rèn)的報文段。因此發(fā)送方更新它的SendBase變量;如果當(dāng)前有未被確認(rèn)的報文段,TCP還要重新啟動定時器。
四、TCP重發(fā)場景
(1)丟失ACK的情況
從主機(jī)B發(fā)往主機(jī)A 的確認(rèn)報文丟失了,這時會發(fā)生超時,主機(jī)A 會重傳相同的報文段。
(2)過早的超時設(shè)置
第二個報文段序號是100,包含20字節(jié)的數(shù)據(jù)。假設(shè)兩個報文段都完好無損的到達(dá)主機(jī)B,并且主機(jī)B為每一個報文段分別發(fā)送一個確認(rèn)。確認(rèn)報文序號分別為100、120。現(xiàn)在假設(shè)在超時之前這兩個報文段中沒有一個確認(rèn)報文到達(dá)主機(jī)A。當(dāng)超時事件發(fā)生時,主機(jī)A重傳序號92的第一個報文段,并重啟定時器。只要第二個報文段的ACK在新的超時發(fā)生以前到達(dá),第二個報文段將不會被重傳。
(3)累計ACK的情況
假設(shè)主機(jī)A 與在第二種情況中完全一樣,發(fā)送兩個報文段。第一個報文段的確認(rèn)報文在網(wǎng)絡(luò)中丟失,但在超時事件發(fā)生之前主機(jī)A收到一個確認(rèn)號為120的確認(rèn)報文。主機(jī)A因而知道主機(jī)B已經(jīng)收到了序號119及之前的所有字節(jié);所以主機(jī)不會重傳這兩個報文段中的任何一個。
五、快速重傳
超時觸發(fā)重傳存在的問題之一是超時周期可能相對較長。當(dāng)一個報文段丟失時,這種長超時周期迫使發(fā)送方延遲重傳丟失的分組,因而增加了端到端時延。幸運(yùn)的是發(fā)送方通常可以在超時事件發(fā)生之前通過注意所謂冗余ACK來較好地檢測丟包情況。冗余ACK就是再次收到接收方發(fā)送地ACK,而發(fā)送方之前已收到過對該報文段地確認(rèn)。
下圖為TCP ACK產(chǎn)生產(chǎn)生的幾種情況。
圖中第三種情況會發(fā)送冗余ACK,如果一個報文段丟失,就很可能引起許多一個接一個的冗余ACK。如果TCP發(fā)送方收到3個相同數(shù)據(jù)的ACK,則說明在這個已經(jīng)被確認(rèn)過3次的報文段之后的報文段已丟失。所以一旦收到3個冗余ACK,TCP就進(jìn)行快速重傳即在該報文段的定時器過期之前重傳丟失的報文段。下圖為采用快速重傳的代碼:
總結(jié)
以上是生活随笔為你收集整理的TCP往返时延的估计和超时的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux学习之系统编程篇:与信号捕捉有
- 下一篇: Linux学习之系统编程篇:利用 SIG