在 .NET 中保持活动套接字检查的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/169170/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
what is the best way to do keep alive socket checking in .NET?
提问by Greg Dean
I am looking for a way to do a keep alive check in .NET. The scenario is for both UDP and TCP.
我正在寻找一种在 .NET 中进行保持活动检查的方法。该方案适用于 UDP 和 TCP。
Currently in TCP what I do is that one side connects and when there is no data to send it sends a keep alive every X seconds.
目前在 TCP 中,我所做的是一侧连接,当没有数据要发送时,它每 X 秒发送一次保持活动状态。
I want the other side to check for data, and if non was received in X seconds, to raise an event or so.
我希望另一方检查数据,如果在 X 秒内收到 non ,则引发事件左右。
One way i tried to do was do a blocking receive and set the socket's RecieveTimeout to X seconds. But the problem was whenever the Timeout happened, the socket's Receive would throw an SocketExeception and the socket on this side would close, is this the correct behaviour ? why does the socket close/die after the timeout instead of just going on ?
我尝试做的一种方法是进行阻塞接收并将套接字的 RecieveTimeout 设置为 X 秒。但问题是每当超时发生时,套接字的 Receive 会抛出一个 SocketExeception 并且这边的套接字会关闭,这是正确的行为吗?为什么套接字在超时后关闭/死亡而不是继续?
A check if there is data and sleep isn't acceptable (since I might be lagging on receiving data while sleeping).
检查是否有数据和睡眠是不可接受的(因为我可能会在睡眠时延迟接收数据)。
So what is the best way to go about this, and why is the method i described on the other side failing ?
那么解决这个问题的最佳方法是什么,为什么我在另一端描述的方法失败了?
回答by Greg Dean
If you literally mean "KeepAlive", try the following.
如果您的字面意思是“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);
}
Note the time units are in milliseconds.
请注意,时间单位以毫秒为单位。
回答by qbeuek
According to MSDN, a SocketException thrown when ReceiveTimeout is exceeded in Receive call will notclose the socket. There is something else going on in your code.
根据 MSDN,在 Receive 调用中超过 ReceiveTimeout 时抛出的 SocketException不会关闭套接字。您的代码中还有其他内容。
Check the caught SocketException details - maybe it's not a timeout after all. Maybe the other side of the connection shuts down the socket.
检查捕获的 SocketException 详细信息 - 也许它毕竟不是超时。也许连接的另一端关闭了套接字。
Consider enabling network tracing to diagnose the exact source of your problems: look for "Network Tracing" on MSDN (can't provide you with a link, since right now MSDN is down).
考虑启用网络跟踪来诊断问题的确切来源:在 MSDN 上查找“网络跟踪”(无法为您提供链接,因为现在 MSDN 已关闭)。
回答by TToni
Since you cannot use the blocking (synchronous) receive, you will have to settle for the asynchronous handling. Fortunately that's quite easy to do with .NET. Look for the description of BeginReceive() and EndReceive(). Or check out this articleor this.
由于您不能使用阻塞(同步)接收,您将不得不接受异步处理。幸运的是,使用 .NET 很容易做到这一点。查找 BeginReceive() 和 EndReceive() 的描述。或者查看这篇文章或这个。
As for the timeout behaviour I found no conclusive description of this. Since it's not documented otherwise you have to assume that it's the intended behaviour.
至于超时行为,我没有找到对此的结论性描述。由于它没有记录在案,否则您必须假设这是预期的行为。

