Networking
TCP 數據包的緩衝是如何工作的?
如果我在套接字上快速連續寫入幾次(使用 POSIX 函式
write
),通常我寫入的所有數據都會在單個 TCP 數據包中發送。除非我寫得太多,或者除非我在兩次寫之間等待太久。核心是否緩衝了我在套接字上寫入的數據並定期發送數據包?還是 libc 處理這個?核心在發送數據包之前等待多長時間?我可以要求立即發送一個大部分為空的數據包嗎?UDP 或其他協議的處理方式是否不同?
我很想了解所有這些工作是如何工作的,但我很難找到有關該主題的資訊。
您的作業系統可能會在發送之前進行一些短期緩衝。例如,Linux 手冊頁
tcp(7)
提到了TCP_NODELAY
禁用該選項的選項(另請參閱setsockopt(2)
):
TCP_NODELAY
如果設置,則禁用 Nagle 算法。這意味著即使只有少量數據,也總是盡快發送段。不設置時,記憶體數據直到有足夠的量發送出去,從而避免頻繁發送小包,導致網路使用率低。此選項被
TCP_CORK
;覆蓋 但是,設置此選項會強制顯式刷新掛起的輸出,即使TCP_CORK
目前已設置。Nagle 算法是實際的緩衝算法。如果我正確地遵循了麵包屑,RFC 1122似乎是它目前有效的定義。
它是核心,而不是 libc。C 庫為 stdio 流 (
FILE *
) 進行緩衝,但write()
直接send()
進入核心。使用 UDP,數據報的大小很重要並且對上層可見,因此在那裡不可能進行類似的修改。