TCP 流量控制 (TCP Flow Control) 一文,
介紹了 滑動視窗 (Sliding Window) 的概念,
說明透過 回饋 (feedback) 機制,調整視窗大小,改善傳輸效率。
然而某些狀況下,滑動視窗的運作,會產生嚴重的問題,
稱為 — — 傻瓜視窗症候群 (Silly Window Syndrome, SWS),
本篇即是介紹這種症狀 😂,並說明其解法。

傻瓜視窗症候群
(Silly Window Syndrome, SWS)
一家餐廳要賺錢,換桌率 很重要,
最賭爛就是,客人進食 或 廚師上菜 有夠慢 🙄,
更可怕的是兩者同時發生…

維護應用層資料的 — — 傳輸控制協定 (Transmission Control Protocol, TCP) ,
由於 發送者 (Sender) 與 接收者 (Recipient) 傳輸、讀取的速率不相等,
接收端 會將資料暫存在 接收緩衝區 (Receiving Buffers),
並等待 應用層讀取後 (消化),再從 接收緩衝區 中清除。
餐桌,就如 接收緩衝區, 客人進食,為 應用層讀取 (消化), 廚師做菜,則為 傳送端 產生資料。
這種「接收端 之 應用程序 讀取 (消化)」 or 「傳送端 產生資料」 速度很慢,
造成的網路效率低弱,就稱為 — — 傻瓜視窗症候群 (Silly Window Syndrome, SWS),又稱 糊塗窗口綜合症。
傳送端 SWS
典型的 傳送端 SWS 為:
「傳送端 應用程式 產生資料速度很慢」,
最極端的狀況就是,一次只傳送 1 byte 的資料..
如許多 Telnet 鍵盤操作,會產生 1 byte 的資料並馬上送出。
可別忘記,TCP 每次 發送 與 接收 單位為: TCP 區段 (TCP Segment),
光加上 TCP 表頭 (Header) 可能就 40 bytes 了,
加上資料 1 byte,總共 41 bytes,
這種沒效率的狀況,又稱 小封包問題 (small packet problem)。

就像花了三千買禮物給一位學妹,
只換得她一聲:「謝謝你 😍 你對我就像哥哥一樣好」。
兄弟,不值得啊… (過來人😭)
Nagle 演算法 (Nagle's Algorithm)
Nagle 演算法處理的是發送端反覆寫入很小資料塊時的 small-packet problem。它的核心不是「第一筆資料」或單一 data.length 的特例,而是:當連線上已有尚未確認的資料時,先累積新的小資料;收到 ACK 或累積到可送滿一個 MSS 時再送出。若沒有未確認資料,小資料可以立即送出。
簡化心法:unacknowledged data 存在時,不再連續送小 segment;等 ACK 或等到足以送滿 MSS。
MSS 是端點在 SYN 中各自宣告的「我願意接收的 TCP payload 上限」,兩個方向可不同;它不是把區段總長固定住。實際可送的 payload 還受 Path MTU、IP/TCP options、壅塞視窗與接收視窗影響,路徑改變時也可能調整。未宣告 MSS 時,IPv4 的傳統預設值是 536 bytes。
Nagle 與 delayed ACK 的組合確實可能讓互動式、少量寫入的協定增加延遲,但不應一概為 Web Server 關閉。先量測延遲與封包行為;只有應用的訊息邊界與低延遲需求明確時,才考慮在該 socket 使用 TCP_NODELAY。在 NGINX,tcp_nodelay on 是啟用 TCP_NODELAY,並不是「關閉」它。
接收端 SWS
接收端 SWS 的重點不是把任何空間都立刻公告出去:如果接收端每讀出一兩個 byte 就把很小的 rwnd 增量告訴對方,傳送端便可能送出一串很小的 segment。
Clark 方案 (Clark's Solution)
Clark 的建議是避免宣告很小的非零視窗。接收端可以在緩衝區沒有空間時宣告 rwnd = 0;之後等到可容納一個 MSS、至少接收緩衝區的一半,或實作選定的合理門檻,再宣告較有用的非零視窗。這是避免小視窗更新,不是每次收到資料就固定回 rwnd = 0。
收到 zero window 的傳送端不會任意繼續送新資料,但會以 persist timer 發送 zero-window probe,避免 window update 遺失後雙方永久等待。
延遲確認 (Delayed ACK)
Delayed ACK 的主要目的,是減少純 ACK 並盡量和反向資料 piggyback;它不是等待接收緩衝區騰出空間的機制。TCP 會在短暫等待後確認資料;依 RFC 建議,延遲不應超過 500 ms,而且對連續的完整大小 segment,至少每兩個 segment 應回覆一個 ACK。實作通常使用比上限短得多的自適應計時器。
Nagle 與 delayed ACK 在互動式、小寫入的應用上可能形成額外等待,但這不表示 delayed ACK 會「讓傳送端誤解」或必然造成重送。是否調整兩者,應以延遲量測與特定協定行為判斷。
在〈TCP 傻瓜視窗症候群 (Silly Window Syndrome, SWS)〉中有 2 則留言
之後的新資料,皆至於 發送緩出區 中累積、等待
上面那行的發送緩”出”區 是 發送緩”衝”區吧 !?
感謝提醒!已修正 😄