2011-07-17 45 views
4

根據this Socket FAQ article,Nagle的算法是許多算法之一,可能會導致一堆數據位於TCP緩衝區中,而不會觸及導線。 Nagle算法的延遲可以達到200ms。TCP Nagle刷新發生了什麼?

出於某種原因,Nagle算法可以被關閉完全,但刷新一次。這真讓我感到困惑。爲什麼沒有辦法說「只有這一次,不要等待更多的數據,就好像Nagle的200毫秒的時間一樣。」

難道這不是完全合理的,並且始終在Nagle之間取得良好的平衡,並且始終從頭開始實施自己的協議?

+0

Nagle的算法不會延遲你的第一個send()。如果第一個send()的確認尚未到達,它只會延遲你的第二個send()。所以避免Nagle算法延遲的一種方法是將盡可能多的send()操作合併爲一個。 – hagello

回答

1

好問題。我想沒人確實需要它或他們繞過它。如果我沒有記錯,啓用TCP_NODELAY立即推送數據。然後你可以禁用它。

當然,這是以兩次系統調用「沖洗」爲代價的高昂代價。你在可能做:send(2),在Unix上的實現有一個flags參數。你可以實現自己的國旗,如:MSG_JUSTPUSHIT(好吧,也許是別的名字),並考慮在tcp_output

+0

找到[另一個問題](http://stackoverflow.com/questions/5523565/socket-flush-by-temporarily-enable-nodelay),它也建議啓用/禁用TCP_NODELAY以實現Nagle刷新。 –

+0

@romkyns是的,但是'發送'標誌仍然是可取的。 – cnicutar

+0

我無法找到Windows的「發送」等效命令... –

0

在對性能敏感的應用程序中,由Nagle算法引入的延遲是一個問題,通過使用分散/聚集IO(例如,writev())或通過實施緩衝來完全禁用Nagle算法並在軟件中模擬其批處理容易在需要的軟件中)。作爲額外的獎勵,這樣做會削減一些系統調用開銷。

或者,您可以打開兩個單獨的套接字並在其中一個上禁用Nagling。請記住,在一個套接字上發送的數據不一定會與另一個套接字同步。

+0

我有一個應用程序發送大量的數據單向,但也每隔幾秒交互式溝通。這意味着無論是永遠在線還是永遠都不夠好。看來,Nagle沖洗將是解決這個問題的最簡單方法。 –

+0

在上面的帖子中增加了另一個想法(兩個套接字)。 – duskwuff

+0

不幸的是,這兩個過程需要同步。 –