【发布时间】:2014-06-19 05:17:57
【问题描述】:
我正在尝试在 .NET 中编写一个非常简单的 TCP 服务器,它只为一个客户端处理一个连接,而我的挑战是检测半开连接。
根据这个无处不在的 MSDN 代码...
// This is how you can determine whether a socket is still connected.
bool blockingState = client.Blocking;
try
{
byte [] tmp = new byte[1];
client.Blocking = false;
client.Send(tmp, 0, 0);
Console.WriteLine("Connected!");
}
catch (SocketException e)
{
// 10035 == WSAEWOULDBLOCK
if (e.NativeErrorCode.Equals(10035))
Console.WriteLine("Still Connected, but the Send would block");
else
{
Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);
}
}
finally
{
client.Blocking = blockingState;
}
...我认为这样做的目的是发现任何现实世界的连接问题(例如拔掉远程客户端的网络电缆)并抛出所需的异常。
然而,我也明白发出 Send() 只会导致数据被放入套接字的底层发送缓冲区......所以很明显它不会仅仅因为出现问题而失败客户端。
我读到您需要执行后续 Receive() 才能实际获得零长度发送测试的结果。但是,我的服务器目前正在使用持续的 BeginReceive 方法,在这种方法中,一旦我真正接收到数据并对其进行处理,我就会启动 BeginSend(),然后发出另一个 BeginReceive()。
换句话说,在执行“MSDN 测试”时,我已经有一个有效的待处理接收。 那不会以某种方式感知缺少 ACK 并发出错误信号吗?
谢谢
【问题讨论】:
-
任何中间路由器都被允许丢弃这个数据包,因为它没有数据,所以我认为这个解决方案一般来说是不可靠的。也就是说,
Send成功完成后,client.Connected的值是多少? -
Stephen,拔掉对端网线,Send()返回成功后client.Connected的值为true。
-
你从哪里读到这个关于后续接收的废话?它会收到什么?
-
不幸的是我找不到链接,但无论如何,让我们暂时假设它是无稽之谈;那么我该如何避免半开连接问题呢?