TCP保持活动频率不一致

时间:2014-09-01 09:30:43

标签: .net windows sockets tcp wireshark

我在.NET应用程序中配置了一个TCP套接字,每15分钟发送一次Keep-Alive数据包。请注意,在.NET世界中,只能使用低级Socket.IOControl API来传递此参数(而不是简单地启用 Keep-Alives)表示本机结构的字节。

观察以下传出的Keep-Alives的Wireshark捕获:

Wireshark Capture

在12:35到14:05之间一切都按计划进行(Keep-Alives每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分钟)后断开连接,因此我们无法承受这些间隔变化如此频繁。对我们来说,构建应用程序级别的心跳和其他此类用户级解决方案也有点痛苦 - 太多系统需要更改。

可能导致此不一致行为的原因是什么?

1 个答案:

答案 0 :(得分:2)

来自RFC 1122 section 4.2.3.6

  

只有在间隔内没有收到连接的数据或确认数据包时,才能发送保持活动的数据包。

这意味着,如果在您的情况下,保留活动数据包将在应用程序发送或接收最后一个数据包后15分钟发送。如果您的应用程序闲置,它将每15分钟发送一次。