客戶的一個TCP程序在空閒的時候,每200毫秒發送端會發送8個字節的心跳。 發現有近3秒的時
間不發送這種心跳, 業務只好把socket關了,關閉的時候,發現有13個心跳數
據合在一起發送。
我查了一下TCP發送代碼(tcp_output.c,196行),它不發送8個字節的數據是爲了避免silly
window syndrome。 詳見TCP/IP 詳解 第一卷 22.3 小節。 後來採取以下方法之一:
一、 用TCP_NODELAY 禁止Nagle 算法
二、 在心跳數據後面填充,直至大小爲MSS
解決問題。
Nagle 算法的大意:
TCP 連接的發送方如果還有發出去的數據沒有被ACK,那麼小數據不會被立即發送直到那個數據被ACK,這些小數據會被累積起來放在一個segment被髮送出去。
Nagle 也可以這樣理解: 對方回覆(回ACK)得慢,我方發送得也慢。 在此期間,積累小的數據。
Nagle 算法的目的是充分利用帶寬,不頻繁地發送小的數據,因爲爲了發送一個小數據,要在TCP/IP層和鏈路層加上頭,開銷是很大的。 這種想法是好的,但是干擾了某些想定時發送小數據的TCP程序。 所以有時候要禁止Nagle 算法,辦法就是加上對socket 設置 TCP_NODELAY 選項。
參考 《TCP/IP 詳解 第一卷 》19.4 小節。