tcp重傳機制 對端滑動窗口一直為0時如何處理?
有一個長連,應用層write 1K位元組數據到os的socket buffer後,對端機器滑動窗口一直為0,或者發送一部分數據後,一直未收到ack,數據一致無法發送到對端,tcp會如何處理當前的這個數據,是超過重試次數後通知應用層還是一直嘗試重發?
如果一直留著發送緩存中,tcp的超時重傳會持續多久,如果應用層一直不主動干預,留在發送緩存的數據是不是會一直存在呢
在回答這個問題之前,先問一個問題,通信雙方的客戶端與伺服器是AI機器人哇?不是!那是什麼?是兩個不夠智能的僵硬機器,根據人類的指令輸入來完成通信。
通信過程繁複兀雜,但撥開雲霧會發現,其實通信過程可以分為兩大類:
1)事件觸發(event trigger) 簡稱ET
2)定時器觸發 ( timer trigger) 簡稱 TT
我們以一個例子(TCP建立連接的三次握手)來說明兩者的區別:
1.1 事件觸發
A主動發起對B的TCP連接(SYN),這是ET還是TT呢? 是ET,因為是位於A後的老王發出的指令,比如在瀏覽器里輸入B 的網址,然後觸發TCP連接
1.2 定時器觸發
但是如果SYN在發給B 的過程中丟了呢?是否還需要老王再次提交指令?如果是,那這個TCP協議棧就太不友好了,事實上商用的TCP會緩存用戶的連接指令,並啟動一個重傳定時器,定時器超時,無需老王的干預,TCP會自動重傳連接指令,這就是定時器觸發
2.1 事件觸發
假設B接收到A的連接請求,這個就是事件觸發,是由於外部事件而觸發的動作,動作是什麼呢? 發SYN + ACK。
2.2 定時器觸發
B同樣擔心自己的SYN + ACK丟失,所以也會啟動一個重傳定時器,如果在超時時間內沒有接收到A的ACK,則會觸發重傳動作,如果收到ACK,則關閉定時器。
3 事件觸發
假設A接收到B的SYN + ACK,這是一個外部事件觸發的動作,動作是
1)關閉重傳定時器
2)發送ACK
3)將TCP狀態更新為established
對於3.2里的ACK要不要啟動重傳定時器?不需要,如果是,會無限循環到永遠。
以上通過3-way 握手解釋了事件觸發以及定時器觸發的區別,對於題主的問題就非常好回答了。
對於應用層提交給TCP的數據(事件觸發),觸發的動作是
1)發送數據 並緩衝數據
2)為數據啟動重傳定時器
如果接到對方ACK,事件觸發的動作是
1)關閉定時器
2)釋放緩存
如果定時器超時也沒有接收到ACK,則定時器觸發,動作是
1)重傳數據
2)記錄重傳次數
如果重傳次數滿,比如重傳8次,則是事件觸發,動作是
1)reset 或關閉TCP連接
2)通知應用層出錯
再來回答第二個問題,B告訴A,window size =0,則A認為這是一個外部事件,觸發一個動作
1)啟動探測定時器( persistent timer)
如果在PT超時之前接收到B的window &>0, 則事件觸發,動作為
1)關閉PT
2)有數據則繼續發送數據
3)更新自己的滑動窗口右側
如果在PT超時之前沒有接收到B window更新,則定時器觸發,動作為
1)發送一個byte 合法數據(滑動窗口內)或非法數據(滑動窗口外)
2)刷新定時器
3)記錄超時次數
如果超時次數到達極限,則事件觸發,動作為
1)reset 或關閉TCP連接
2)通知應用層出錯原因
整個通信過程只需要一次用戶輸入(用戶事件),接下來的通信過程全部依賴事件觸發、定時器觸發而產生的動作自動完成,或如行雲流水(順利)或磕磕絆絆(不順利),但無需用戶干預。
你可以很容易地重現這個場景,再用 tcpdump 看看就知道了。
接收端通告的窗口大小變成0,發送端會發一個1位元組的段(就是下一位元組的數據,沒新的數據段發送的時候發一個ack)(TCP零窗口探測),強制接收端重新宣告下一個期望的位元組和窗口大小。如果接收方回復窗口大小仍然為零,則發送方的探測定時器加倍。沒有收到ACK時,發送探測包的最大次數之後連接超時。
如果是linux,關閉滑動或者縮小其rmem
有知友提到了0窗口探測,這裡我做一個補充, 窗口探測是發送端滑動窗口為零時進行的,當接收方滑動窗口變零後,也就是接收到發送方滑動窗口裡的全部數據後,會將最後一個位元組序號+1作為確認號返回發送方,發送方的滑動窗口此時變零,引起死鎖(因為窗口為0,沒東西發了,接收方沒東西收也不會反饋),才需要進行0窗口探測的,;如果這個確認數據包中途丟失,會出現接收方滑動窗口為0但是發送方還是維持之前的大小,此時發送方還會通過超時重傳機制發送給接收方,接收方一樣會返回確認,並不是接收方滑動窗口為0時,發送方就會進行0窗口探測,而是發送方為0時才進行 。
----以下為原答案---
對端滑動窗口為0,你發過去的數據包也會被丟棄吧,因為沒有收到對端新的期望的確認號,發送端在發送緩存中的已發送但未確認的位元組就不會刪,只能進行超時重傳,應用層不用多次再發。具體可以參考謝希仁著的《計算機網路》運輸層那一章,tcp可靠傳輸的實現和tcp流量控制兩節內容,對這種情況有詳細論述。
tcp重傳有一個往返時間RTT 是隨機的 有一個公式
tcp通信要基於ip的可達性 像你說的 tcp發過去包 多端存緩存里 都無法處理了 可見對端網路連通性極差
至於題主如果想研究一些抬杠的東西 建議你研究一下qos 看一看緩存里的數據處理過程
推薦閱讀:
※為什麼TCP4次揮手時等待為2MSL?
※在計算機領域中,有哪些令你拍案叫絕的思想?
※乙太網與互聯網有什麼區別?
※埠號和協議號的區別在哪裡?
※10MB寬頻會有這樣的速度嗎?