2014-09-01 57 views
1

我在.NET應用程序中配置了一個TCP套接字,每15分鐘發送一次Keep-Alive數據包。請注意,在.NET世界中,只能使用低層的Socket.IOControl API來傳遞表示本地結構的字節,而只能操縱此參數(而不是簡單地使用啓用 Keep-Alives)。TCP保持活躍頻率不一致

觀察傳出保持活動的低於Wireshark的捕獲:

Wireshark Capture

一切都爲12:35和14:05之間計劃(保持活動中,每15分鐘發送),但之後,這些數據包的發送頻率開始大幅變化(24分鐘,15分鐘,29分鐘,1小時4分鐘)。除此之外,應用程序在此期間的行爲完全如預期。

這段時間過後不久,Keep-Alive跨度又恢復到15分鐘。


僅供參考,我已經寫設置參數的代碼如下:

private void SetKeepAlive(uint time, uint interval, SocketOptionLevel level) 
{ 
    // The native structure for this is defined in mstcpip.h as: 
    //struct tcp_keepalive { 
    //u_long onoff; 
    //u_long keepalivetime; 
    //u_long keepaliveinterval; 
    //}; 

    var inValue = new[] { Convert.ToUInt32(true), time, interval } 
        .SelectMany(BitConverter.GetBytes) 
        .ToArray(); 

    var outValue = new byte[sizeof(uint)]; 

    Socket.SetSocketOption(level, SocketOptionName.KeepAlive, true); 
    Socket.IOControl(IOControlCode.KeepAliveValues, inValue, outValue); 
} 

...調用相當於:

SetKeepAlive(900000, 1000, SocketOptionLevel.Socket); 

的這些Keep-Alives的目的是爲了防止我們的某些網絡硬件在超時(大約30分鐘)後斷開連接,所以我們無法負擔這些我非常不同。對於我們來說,構建應用程序級心跳和其他類似的用戶級解決方案也是一件痛苦的事情 - 需要改變的系統太多了。

什麼可能導致這種不一致的行爲?

+0

連接總是閒置嗎? keep-alive的用法是定期交換數據包。如果通過交換應用程序數據已經實現這一點,則不會發送保持活動,即每當應用程序數據交換時,定時器就會重置。 – 2014-09-01 09:59:55

+0

如果在此期間定期發送數據報,是否抑制了保活(即計時器已重置)?這在邏輯上是合理的,但我的印象是(不記得原因),事實並非如此。 – Ani 2014-09-01 12:15:46

+0

是的,保活只用於填補空閒時間。如果沒有閒着,那就沒有必要保持活力了。 TCP是一個非常聰明的協議:) – 2014-09-01 12:23:23

回答

2

從RFC 1122 section 4.2.3.6

保持活動時已經接收到一個時間間隔內的連接沒有數據或確認數據包的數據包必須只發送。

這意味着,如果在您的情況下保持活動數據包將在應用程序發送或接收最後一個數據包15分鐘後發送。如果您的應用程序空閒,它將每15分鐘發送一次。

+0

+1,用於引用TCP規範:) – jgauffin 2014-09-01 12:40:48