我正在寻找一种在.NET中进行保持活动检查的方法。该方案适用于UDP和TCP。
目前在TCP中,我所做的是一方连接,当没有数据要发送时,它每隔X秒发送一次保持活动。
我希望对方检查数据,如果在X秒内收到非数据,则提出事件左右。
我尝试做的一种方法是进行阻塞接收并将套接字的RecieveTimeout设置为X秒。但问题是每当Timeout发生时,套接字的Receive会抛出一个SocketExeception并且这边的套接字会关闭,这是正确的行为吗?为什么套接字在超时后关闭/死亡而不仅仅是继续?
检查是否有数据和睡眠是不可接受的(因为我可能在睡觉时接收数据时滞后)。
那么最好的方法是什么呢?为什么我在另一方描述的方法失败了呢?
答案 0 :(得分:17)
如果您的字面意思是“KeepAlive”,请尝试以下操作。
public static void SetTcpKeepAlive(Socket socket, uint keepaliveTime, uint keepaliveInterval)
{
/* the native structure
struct tcp_keepalive {
ULONG onoff;
ULONG keepalivetime;
ULONG keepaliveinterval;
};
*/
// marshal the equivalent of the native structure into a byte array
uint dummy = 0;
byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
BitConverter.GetBytes((uint)(keepaliveTime)).CopyTo(inOptionValues, 0);
BitConverter.GetBytes((uint)keepaliveTime).CopyTo(inOptionValues, Marshal.SizeOf(dummy));
BitConverter.GetBytes((uint)keepaliveInterval).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);
// write SIO_VALS to Socket IOControl
socket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);
}
答案 1 :(得分:1)
根据MSDN,在接收呼叫中超过ReceiveTimeout时抛出SocketException将不会关闭套接字。您的代码中还有其他内容。
检查捕获的SocketException详细信息 - 也许它毕竟不是超时。也许连接的另一端关闭了套接字。
考虑启用网络跟踪来诊断问题的确切来源:在MSDN上查找“网络跟踪”(无法为您提供链接,因为现在MSDN已关闭)。
答案 2 :(得分:0)