我在.NET应用程序中配置了一个TCP套接字,每15分钟发送一次Keep-Alive数据包。请注意,在.NET世界中,只能使用低级Socket.IOControl
API来传递此参数(而不是简单地启用 Keep-Alives)表示本机结构的字节。
观察以下传出的Keep-Alives的Wireshark捕获:
在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分钟)后断开连接,因此我们无法承受这些间隔变化如此频繁。对我们来说,构建应用程序级别的心跳和其他此类用户级解决方案也有点痛苦 - 太多系统需要更改。
可能导致此不一致行为的原因是什么?
答案 0 :(得分:2)
来自RFC 1122 section 4.2.3.6:
只有在间隔内没有收到连接的数据或确认数据包时,才能发送保持活动的数据包。
这意味着,如果在您的情况下,保留活动数据包将在应用程序发送或接收最后一个数据包后15分钟发送。如果您的应用程序闲置,它将每15分钟发送一次。