【发布时间】:2011-04-15 17:51:07
【问题描述】:
我一直在使用 C# 编写套接字客户端程序,我想知道如何检测套接字的另一端何时“不正常”地断开自身连接,例如拔掉网线或硬重置。
我在下面有这些函数来访问套接字,根据 SO 问题 here 和这个 MSDN article,检查断开连接的套接字的最佳方法是发送长度为 0 的 1 字节消息。如果抛出异常并且 WSAEWOULDBLOCK 不是错误代码,则套接字断开连接。我已经尝试过了,但是在硬重置服务器连接后,客户端将调用Send(new byte[1], 0, 0, SocketFlags.None) 并成功返回,然后Receive() 命令立即返回 WSAEWOULDBLOCK 错误。
什么给了??
下面是我的代码。 _socket 设置为非阻塞模式:
private int nonBlockRecv(byte[] recvBytes, int offset, int size, SocketFlags sf)
{
int bytesRecv = 0;
while (true)
{
try
{
nonBlockSend(new byte[1], 0, 0, sf);
bytesRecv = _socket.Receive(recvBytes, offset, size, sf);
break;
}
catch (SocketException excp)
{
if (excp.ErrorCode != 10035) // WSAEWOULDBLOCK
throw excp;
}
}
return bytesRecv;
}
private int nonBlockSend(byte[] sendBytes, int offset, int size, SocketFlags sf)
{
int bytesSent = 0;
while (true)
{
try
{
_socket.Send(sendBytes, offset, size, sf);
break;
}
catch (SocketException excp)
{
if (excp.ErrorCode != 10035) // WSAEWOULDBLOCK
throw excp;
}
}
return bytesSent;
}
编辑:这可能是有益的,但服务器是 Windows Mobile 设备。我在另一个线程中读到,不同的操作系统可能会在它们死亡时发送套接字关闭信号。也许 Windows Mobile 操作系统不这样做?
【问题讨论】:
-
1 字节消息的长度怎么可能为零? :-)
-
好问题哈哈。这就是 MSDN 文章所说的。但是,如果我确实将大小设置为 1,那么它就可以工作!我想这很明显,但是额外的位通过流发送到服务器端套接字。我希望 Receive() 抛出一个异常,而不是在套接字关闭时会阻塞一个异常,但情况似乎并非如此......