TCP系列42—拥塞控制—5、Linux中的慢启动和拥塞避免(二)
在本篇中我們繼續(xù)上一篇文章wireshark的示例講解,上一篇介紹了一個綜合示例后,本篇介紹一些簡單的示例,在讀本篇前建議先把上一篇讀完,為了節(jié)省篇幅,本篇只針對一些特殊的場景點報文進行講解,不會像上一篇一樣對每個報文都進行講解并隨報文更新相關(guān)狀態(tài)變量的值了。
一、wireshark示例
本篇示例的TCP測試仍然設(shè)置初始擁塞窗口為3,并關(guān)閉TSO、GSO等功能。同時設(shè)置wireshark使其不在info列顯示TSopt的信息。
client與server端建立連接后,先發(fā)送一個請求報文No4,server端則立即回復ACK確認包。server端在與client建立連接后休眠1000ms,然后每隔5ms發(fā)送50bytes的數(shù)據(jù)包,總共發(fā)送14次。client端則每收到兩個報文的時候回復一個ACK確認包。最終TCP流如下圖所示,圖中in_flight列是wireshark對于目前還在傳輸中的數(shù)據(jù)量的估計,在這種簡單場景下wireshark的估計與linux是一致的,可以作為參考
No9-No13:No9報文回復了No6和No7兩個報文,server端收到No9報文后,直接更新cwn=cwnd+2=5,此時in_flight=packets_out=1,因此可以額外發(fā)出四個新的數(shù)據(jù)包,即No10-No13。從wireshark中也可以看到發(fā)送完No13后in_flight為250,正好是5個數(shù)據(jù)包的大小。
No14-No18:與No9-No13類似不再重復分析
No19-No22:server端收到No19后,只有150bytes三個數(shù)據(jù)包等待發(fā)送,因此最終只發(fā)出了No20-No22三個數(shù)據(jù)包。
2、慢啟動與ABC、stretched ACK、ACK Compression
ABC(Appropriate Byte Count):是指接收端對于接收到的一個TCP報文,分段反饋多個有效的ACK確認包,如果發(fā)送端收到每個ACK確認包后都會更新cwnd,那么在慢啟動階段可能會導致cwnd增長異常迅速,而且超過鏈路的承載能力,最終降低TCP的性能。這種手段也稱呼為ABC攻擊。
stretched ACK:我們之前介紹延遲ACK時候介紹過,當以SMSS發(fā)送報文的時候,協(xié)議規(guī)定延遲ACK不能超過兩個full-sized報文。但是如果接收端收到的ACK確認包中ack number確認了三個或者以上的full-sized的報文的時候,這個ACK就叫做stretched ACK。stretached ACK原因有多種,最常見的就是ACK報文丟失。
ACK compression:由于中間鏈路的緩存以及和其他TCP連接一起共享緩存等原因,可能會導致ACK報文成堆到達發(fā)送端。這種場景我們就稱呼為ACK壓縮。
對于ACK compression場景,reno擁塞控制就是逐個處理每個ACK報文,這樣就會導致?lián)砣翱谕蝗辉龃?#xff0c;發(fā)送端突然發(fā)出大量的TCP報文,這種突然發(fā)出大量數(shù)據(jù)的行為我們稱呼為burst,影響網(wǎng)絡(luò)平穩(wěn)。另外一方面ACK compression還會影響RTT估計,之前我們介紹過有些擁塞控制算法基于時延來來估計網(wǎng)絡(luò)擁塞情況,因此 ACK compresion還會影響這類基于時延的擁塞控制算法的性能。
在這里我們僅演示一下linux慢啟動對于ABC和stretched ACK的處理場景,擁塞避免階段的處理與慢啟動類似不在示例,如下圖所示我高亮標出了一些ACK報文
No12:可以看到No12相對于No9報文Ack number一共反饋確認了三個數(shù)據(jù)包,這個就是我們說的stretched ACK。可以看到此處linux對于stretched ACK的處理上,直接更新了cwnd=cwnd+3,然后一共發(fā)出了No13-No18六個數(shù)據(jù)包。
No19-No21:可以看到No19相對于No12,ack number只反饋確認了30bytes的數(shù)據(jù),并沒有完整反饋No11這個數(shù)據(jù)包,No20同樣也沒有完整反饋No11這個數(shù)據(jù)包,linux在收到這兩個ACK報文的時候,則會判斷是否完整反饋了之前發(fā)出的No11數(shù)據(jù)包,當發(fā)現(xiàn)沒有完整反饋No11數(shù)據(jù)包的時候并不會更新cwnd。直到linux收到No21這個數(shù)據(jù)包后,發(fā)現(xiàn)之前的No11這個數(shù)據(jù)包已經(jīng)被完整反饋了,因此更新cwnd=cwnd+1,發(fā)出兩個數(shù)據(jù)包。
3、多個數(shù)據(jù)包RTO超時
在之前的綜合示例中我們看到過,一次RTO超時觸發(fā)重傳后,同一個報文的多次RTO超時并不會繼續(xù)更新ssthresh,而隨后的recovery point之前的慢啟動重傳也不會更新ssthresh。但是在recovery point之前的多個數(shù)據(jù)包觸發(fā)的RTO超時則會重新更新ssthresh。一定要記得是不同TCP報文的RTO超時才會更新ssthresh,而linux只有一個RTO定時器。要分清慢啟動重傳和RTO超時重傳的區(qū)別。
這個示例與綜合示例非常類似,不同點在于這次RTO超時的是Seq為451的報文,而且No43對應的報文發(fā)生了兩次RTO超時。下面總結(jié)一下這個示例相對于綜合示例的幾個注意點
No35:可以看到這個loss probe報文是個重傳包,而之前綜合示例中,loss probe報文是一個未發(fā)送過的報文,這里一定要分清,No35的重傳是TLP超時觸發(fā)的,而不是RTO超時觸發(fā)。看不懂的前翻TLP的文章。
No43、No47、No48:No43是一個慢啟動重傳,并不是RTO超時觸發(fā)的,因此不會更新ssthresh,而No47則是No43的RTO超時重傳,因此會更新ssthresh =?max(cwnd/2, 2),實際上在RTO超時發(fā)出No47之前,ssthresh=6,cwnd=4,而RTO超時發(fā)出No47報文后,則更新ssthresh=2,cwnd=1。No48同樣是RTO超時重傳,但是No48和No47是同一個數(shù)據(jù)包的多次連續(xù)RTO超時重傳因此不會更新ssthresh。另外這里可以看到wireshark估計的in_flight的大小與linux的差異,例如在RTO超時重傳No35后,linux計算的in_flight為1,大小實際為50bytes。之前我們已經(jīng)介紹過多個linux和wireshark對數(shù)據(jù)包理解上的差異了。
來自為知筆記(Wiz)
轉(zhuǎn)載于:https://www.cnblogs.com/lshs/p/6038747.html
總結(jié)
以上是生活随笔為你收集整理的TCP系列42—拥塞控制—5、Linux中的慢启动和拥塞避免(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 冀鲁豫军区四分区烈士陵园怎么样
- 下一篇: 从13届全国人大一次会议手电筒主笔能发现