根據this Socket FAQ article,Nagle的算法是許多算法之一,可能會導致一堆數據位於TCP緩衝區中,而不會觸及導線。 Nagle算法的延遲可以達到200ms。TCP Nagle刷新發生了什麼?
出於某種原因,Nagle算法可以被關閉完全,但不刷新一次。這真讓我感到困惑。爲什麼沒有辦法說「只有這一次,不要等待更多的數據,就好像Nagle的200毫秒的時間一樣。」
難道這不是完全合理的,並且始終在Nagle之間取得良好的平衡,並且始終從頭開始實施自己的協議?
根據this Socket FAQ article,Nagle的算法是許多算法之一,可能會導致一堆數據位於TCP緩衝區中,而不會觸及導線。 Nagle算法的延遲可以達到200ms。TCP Nagle刷新發生了什麼?
出於某種原因,Nagle算法可以被關閉完全,但不刷新一次。這真讓我感到困惑。爲什麼沒有辦法說「只有這一次,不要等待更多的數據,就好像Nagle的200毫秒的時間一樣。」
難道這不是完全合理的,並且始終在Nagle之間取得良好的平衡,並且始終從頭開始實施自己的協議?
好問題。我想沒人確實需要它或他們繞過它。如果我沒有記錯,啓用TCP_NODELAY
立即推送數據。然後你可以禁用它。
當然,這是以兩次系統調用「沖洗」爲代價的高昂代價。你在可能做:send(2)
,在Unix上的實現有一個flags
參數。你可以實現自己的國旗,如:MSG_JUSTPUSHIT
(好吧,也許是別的名字),並考慮在tcp_output
。
找到[另一個問題](http://stackoverflow.com/questions/5523565/socket-flush-by-temporarily-enable-nodelay),它也建議啓用/禁用TCP_NODELAY以實現Nagle刷新。 –
@romkyns是的,但是'發送'標誌仍然是可取的。 – cnicutar
我無法找到Windows的「發送」等效命令... –
在對性能敏感的應用程序中,由Nagle算法引入的延遲是一個問題,通過使用分散/聚集IO(例如,writev()
)或通過實施緩衝來完全禁用Nagle算法並在軟件中模擬其批處理容易在需要的軟件中)。作爲額外的獎勵,這樣做會削減一些系統調用開銷。
或者,您可以打開兩個單獨的套接字並在其中一個上禁用Nagling。請記住,在一個套接字上發送的數據不一定會與另一個套接字同步。
我有一個應用程序發送大量的數據單向,但也每隔幾秒交互式溝通。這意味着無論是永遠在線還是永遠都不夠好。看來,Nagle沖洗將是解決這個問題的最簡單方法。 –
在上面的帖子中增加了另一個想法(兩個套接字)。 – duskwuff
不幸的是,這兩個過程需要同步。 –
Nagle的算法不會延遲你的第一個send()。如果第一個send()的確認尚未到達,它只會延遲你的第二個send()。所以避免Nagle算法延遲的一種方法是將盡可能多的send()操作合併爲一個。 – hagello