天天看點

糊塗視窗綜合征 SWS

糊塗視窗綜合征

糊塗視窗綜合征(Silly Window syndrome SWS)是一個發送端與接收端處理包不一緻 導緻出現接收端的通告視窗過小 再導緻發送端視窗過小 進而導緻産生大量的小資料包 這樣的小資料包中頭部占比大 導緻傳輸效率低下 這樣的行為就叫做糊塗視窗綜合征

在網上看到一個例子可以很好的說明這個過程

假設接收方的緩沖區已經滿了 而接受端程式每次隻能處理很少 假設是1個位元組 即接收端維護的接收視窗每次大小都隻有一 倘若沒有避免SWS的方法 從接收端傳回的封包上的通告視窗大小隻有1 那麼發送方發送視窗也隻能發送一個位元組 那麼在資料包中以最小的包來估計 IP20個位元組 TCP20個位元組 那麼這個資料包大小為41 可以看出使用率及其低下 是以我們必須要避免這種情況

避免SWS

因為發送端和接收端都可能出現SWS 是以分别從兩端進行避免

發送端

  1. 到達MSS個位元組的封包段可以發送(Nalge算法 防止網絡中出現大量小資料包)
  2. 發送封包達到通告視窗的最大值的一半時發送(針對于視窗較小的情況)

接收端

  1. 等待視窗增至一個MSS
  2. 等待視窗增至接收端緩沖區一半空閑

取兩者之間最小值時再發送 否則發送視窗大小為零

延遲确認機制

在接收端收到資料時先不進行回複确認 接收端在确認收到的封包段之前一直等待 直到緩存有足夠的空間為止 這樣可以使得發送端在這期間視窗不進行滑動 這樣就避免了SWS,而且還減少了網絡中的資料包 其中延遲确認機制的逾時時間應小于500ms 實踐中最大取200ms(延遲确認機制和Nagle算法在一些特殊情況下可能造成死鎖 Nagle算法在同一時刻隻傳遞一個包 即遵循停等規程(stop-and-wait) 那麼有可能接收端Nagle等待ACK 發送端延遲确認 即造成死鎖 造成無謂的時延(Nagle因為停等規程本來時延就高于一般無Nagle的傳輸)

零視窗

既然接收端SWS避免會防止發送小的資料包 那麼在接收端有資料但不足已發送時會發生什麼呢?會出現零視窗的情況 即接收端回複的ACK中的視窗選項為0,因為流量控制是基于通告視窗的 視窗為零的時候發送端視窗為零 不再發送資料。當接收端程式處理完成後的資料到達SWS的時候 從零視窗中恢複 發送一個Update Window,因為視窗更新ACK中一般不包含資料 其不消耗序列号 是以是不可靠的,這就出現了一種問題 如果這個視窗更新丢失那麼就會出現這樣一種情況:接收端緩沖區空閑等待發送端資料 發送端等待接收端的視窗更新 即出現了死鎖

其實這種情況解決的方法也很簡單 即發送端持續性發送視窗探測(window probe) 因為視窗探測中包含一個位元組的資料 占序列号 是以是可靠的 一定會得到一個視窗更新 其後的機制類似于karn算法