TCP/IP詳解學習筆記(12)-TCP的超時與重傳

超時重傳是TCP協議保證數據可靠性的另外一個重要機制,其原理是在發送某一個數據之後就開啓一個計時器,在必定時間內若是沒有獲得發送的數據報的ACK報文,那麼就從新發送數據,直到發送成功爲止。算法

1.超時

超時時間的計算是超時的核心部分,TCP要求這個算法能大體估計出當前的網絡情況,雖然這確實很困難。要求精確的緣由有兩個:(1)定時長久會形成網絡利用率不高。(2)定時過短會形成屢次重傳,使得網絡阻塞。因此,書中給出了一套經驗公式,和其餘的保證計時器準確的措施。緩存

1.1.遞推公式概說

最先的TCP曾經用了一個很是簡單的公式來估計當前網絡的情況,以下網絡

R<-aR+(1-a)M併發

RTP=Rbspa

其中a是一個經驗係數爲0.1,b一般爲2。注意,這是經驗,沒有推導過程,這個數值是能夠被修改的。這個公式是說用舊的RTT(R)和新的RTT(M)綜合到一塊兒來考慮新的RTT(R)的大小。可是,咱們又看到,這種估計在網絡變化很大的狀況下徹底不能作出「靈敏的反應」(Jacoboson說的,不是偶說的,呵呵),因而就有下面的修正公式:效率

Err=M-A原理

A<-A+gErr定時器

D<-D+h(|Err|-D)程序

RTO=A+4D方法

具體的解釋請看書的228頁,這個遞推公式甚至把方差這種統計概念也使用了進來,使得誤差更加的小。並且,必需要指出的是,這兩組公式更新,都是在數據成功傳輸的狀況下才進行,在發生數據從新傳輸的狀況下,並不使用上面的公式進行網絡估計,理由很簡單,由於程序已經不在正常狀態下了,估計出來的數據也是沒有意義的。

1.2.RTO的初始化

RTO的初始化是由公式決定的,例如最初的公式,初始的值應該是1。而修正公式,初始RTO應該是A+4D。

1.3.RTO的更新

當數據正常傳輸的狀況下,咱們就會用上面的公式來更新各個數據,並重開定時器,來保證下一個數據被順利傳輸。要注意的是:重傳的狀況下,RTO不用上面的公式計算,而採用一種叫作「指數退避」的方式。例如:當RTO爲1S的狀況下,發生了數據重傳,咱們就用RTO=2S的定時器來從新傳輸數據,下一次用4S。一直增長到64S爲止。

1.4.估計器的初始化

在這裏,SYN用的估計器初始化彷佛和傳輸用的估計器不同(我也沒有把握)造個人理解,在修正公式中,SYN的狀況下,A初始化爲0,D初始化爲3S。

而在獲得傳輸第一個數據的ACK的時候,應該按照下面的公式進行初始化:

A=M+0.5

D=A/2

1.5.估計器的更新

和上面的討論差很少,就是在正常狀況下,用上面的公式計算,在重傳的狀況下,不更新估計器的各類參數。緣由仍是由於估計不許確。

1.6.Karn算法

這不算是一個算法,這應該是一個策略,說的就是更新RTO和估計器的值的時機選擇問題,1.3.和1.5.所說得更新時機就是Karn算法。

1.7.計時器的使用

兩句話:

  1. 一個鏈接中,有且僅有一個測量定時器被使用。也就是說,若是TCP連續發出3組數據,只有一組數據會被測量。
  2. ACK數據報不會被測量,緣由很簡單,沒有ACK的ACK迴應能夠供結束定時器測量。

2.重傳

有了超時就要有重傳,可是就算是重傳也是有策略的,而不是將數據簡單的發送。

2.1.重傳時發送數據的大小

前面曾經提到過,數據在傳輸的時候不能只使用一個窗口協議,咱們還須要有一個擁塞窗口來控制數據的流量,使得數據不會一會兒都跑到網路中引發「擁塞」。也曾經提到過,擁塞窗口最初使用指數增加的速度來增長自身的窗口,直到發生超時重傳,再進行一次微調。可是沒有提到,如何進行微調,擁塞避免算法和慢啓動門限就是爲此而生。

所謂的慢啓動門限就是說,當擁塞窗口超過這個門限的時候,就使用擁塞避免算法,而在門限之內就採用慢啓動算法。因此這個標準才叫作門限,一般,擁塞窗口記作cwnd,慢啓動門限記作ssthresh。下面咱們來看看擁塞避免和慢啓動是怎麼一塊兒工做的

算法概要(直接從書中拷貝)

  1. 對一個給定的鏈接,初始化cwnd爲1個報文段,ssthresh爲65535個字節。
  2. TCP輸出例程的輸出不能超過cwnd和接收方通告窗口的大小。擁塞避免是發送方使用 的流量控制,而通告窗口則是接收方進行的流量控制。前者是發送方感覺到的網絡擁塞的估 計,然後者則與接收方在該鏈接上的可用緩存大小有關。
  3. 當擁塞發生時(超時或收到重複確認),ssthresh被設置爲當前窗口大小的一半(cwnd 和接收方通告窗口大小的最小值,但最少爲2個報文段)。此外,若是是超時引發了擁塞,則 cwnd被設置爲1個報文段(這就是慢啓動)。
  4. 當新的數據被對方確認時,就增長cwnd,但增長的方法依賴於咱們是否正在進行慢啓 動或擁塞避免。若是cwnd小於或等於ssthresh,則正在進行慢啓動,不然正在進行擁塞避免。 慢啓動一直持續到咱們回到當擁塞發生時所處位置的半時候才中止(由於咱們記錄了在步驟2 中給咱們製造麻煩的窗口大小的一半),而後轉爲執行擁塞避免。

補充上面的擁塞避免公式在P238頁。這整個的流程讓我聯想到開車換檔的過程。

2.2.快速重傳和快速恢復算法

這是數據丟包的狀況下給出的一種修補機制。通常來講,重傳發生在超時以後,可是若是發送端接受到3個以上的重複ACK的狀況下,就應該意識到,數據丟了,須要從新傳遞。這個機制是不須要等到重傳定時器溢出的,因此叫作快速重傳,而從新傳遞之後,由於走的不是慢啓動而是擁塞避免算法,因此這又叫作快速恢復算法。流程以下:

  1. 當收到第3個重複的ACK時,將ssthresh設置爲當前擁塞窗口cwnd的一半。重傳丟失的 報文段。設置cwnd爲ssthresh加上3倍的報文段大小。
  2. 每次收到另外一個重複的ACK時, cwnd增長1個報文段大小併發送1個分組(若是新的 cwnd容許發送)。
  3. 當下一個確認新數據的ACK到達時,設置cwnd爲ssthresh(在第1步中設置的值)。這個 ACK應該是在進行重傳後的一個往返時間內對步驟1中重傳的確認。另外,這個ACK也應該 是對丟失的分組和收到的第1個重複的ACK之間的全部中間報文段的確認。這一步採用的是擁 塞避免,由於當分組丟失時咱們將當前的速率減半。

2.3.ICMP會引發從新傳遞麼?

答案是:不會,TCP會堅持用本身的定時器,可是TCP會保留下ICMP的錯誤而且通知用戶。

2.4.從新分組

TCP爲了提升本身的效率,容許再從新傳輸的時候,只要傳輸包含重傳數據報文的報文就能夠,而不用只重傳須要傳輸的報文。

相關文章
相關標籤/搜索