NewReno是在Reno的基礎上,改進了Fast Recovery,主要思想是保證處於network中的packet的總量是飽和的。算法
在Reno算法中,一個超時會致使相應的那個packet的重傳,然而,一個超時發生時,本能夠重傳多個潛在的丟包,但Reno算法沒有這樣實現,這就致使性能不高。網絡
Reno在遇到多包丟失時,存在兩個問題:一個是,大量的包沒有足夠的重複ACK觸發重傳,只能等待超時才能得以重傳。第二個是,即便採起措施(在Partial Acknowledgement一節中已有所討論)避免了超時,也會存在Multiple Fast Retransmits和嚴重的window reduction現象,這些會影響TCP的性能。在Multiple Fast Retransmits一節中,咱們討論了相應的解決方案。NewReno正是在此方案的基礎上進行的改進。性能
NewReno添加一個recover變量,做爲Fast Recovery階段的一個閾值,當sender成功發送到recover所標識的packet時,Fast Recovery階段才結束。這裏成功發送的標誌是收到來自receiver的正常ACK。spa
每當進入Fast Recovery階段時,recover都更新爲high_seq(當前已經發送出去的packet的最大序號),而在進入Fast Recovery階段以前,recover中保持的是上一個Fast Recovery階段更新的recover的值。實際上,recover表示的是當前窗口中,可能的丟包的最大序號,Fast Recovery階段的目標就是恢復這裏面的全部的丟包,所以,recover是Fast Recovery階段的邊界。ip
NewReno不容許Multiple Fast Retransmits,所以在收到3次重複ACK時,若是TCP已經處於Fast Recovery階段,則不會進行Fast Retransmit。而且,即便TCP沒有處於Fast Recovery階段,NewReno還會判斷重複ACK中的序號是否大於當前recover的值(當前recover的值實際是上一個Fast Recovery階段的recover的值)。若是小於,則說明ACK指明的packet是上一輪Fast Recovery已經處理過的packet,其確定已經在上一輪被重傳了,之因此仍然有3次重複ACK,多是亂序或者重複發送receiver端已經存在的packet致使的,並不意味着丟包,所以不須要重傳。若是大於,則說明這是一個顯然的丟包,會進入Fast Recovery進行處理。it
進入Fast Recovery以後,會繼續收到重複ACK,直到收到非重複ACK爲止,這期間的操做與傳統的Reno一致,NewReno的特別之處體如今處理非重複ACK的環節。io
當收到一個非重複ACK時,這個ACK可能響應的是Fast Retransmit重傳的packet,也多是Fast Retransmit以後重傳的packet。因爲多包丟失的存在,這個ACK多是Full ACK或者Partial ACK,對這兩種ACK會採起不一樣的處理方式。ast
若是ack_seq>recover,則該ACK爲Full ACK。它響應了進入Fast Recovery以前sender所發送的所有packet,按規定能夠退出Fast Recovery階段。在退出以前,會將cwnd縮減到min(ssthresh, FlightSize+SMSS),以保證網絡的守恆。class
若是ack_seq<recover,則該ACK爲Partial ACK。在Partial Acknowledgement一節中已經討論過,Partial ACK意味着多包的丟失,所以,NewReno會重傳某些packet。與其餘方案不一樣,NewReno並不重傳Partial ACK中指明的packet,而是目前未被響應的最小的packet,這樣能夠保證重傳始終是從左到右依次進行,保持連續型。與Reno同樣,重傳以後,NewReno縮減cwnd。具體的作法是,首先減去Partial ACK所響應的packet的數量,而後加上SMSS。整體上是爲了保證Fast Recovery結束時,有ssthresh大小的packet在網絡中傳輸。基礎
因爲多包丟失的存在,NewReno針對Partial ACK的處理,仍然不能快速的恢復全部丟失的packet,所以超時會常常發生。當超時發生時,NewReno採起的措施是退出Fast Recovery,並在退出以前將recover的值更新爲當前high_seq。