刚刚搜索了可能的解决方案,以在客户端断开连接时进行验证。
我找到了这个:
public bool IsConnected( Socket s)
{
try
{
return !(s.Poll(1, SelectMode.SelectRead) &&s.Available == 0);
}
catch (SocketException) { return false; }
}
我在主线程中使用一个while循环与thread.sleep(500)并运行Isconnectedmthod,当我通过Visual Studio运行它时,它运行正常,当我单击停止调试时,它实际上在服务器端程序中通知我,但是当我刚去时到bin目录中的exe并启动它-确实的确通知我建立连接,但是当我关闭程序(通常从'x'按钮)或通过任务管理器时,
IsConnected
方法显然仍然返回true ...即时通讯使用一个简单的TCP连接
client = new TcpClient();
client.Connect("10.0.0.2", 10);
服务器:
Socket s = tcpClient.Client;
while(true)
{
if (!IsConnected(s))
MessageBox.Show("disconnected");
}
(它正在线程btw上运行)。
有什么建议吗?
当客户端关闭时,我什至试图关闭连接:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
client.Close();
s.Close();
Environment.Exit(0);
}
不知道该怎么办
最佳答案
您所要求的是不可能的。除非尝试发送连接,否则TCP将不会报告连接错误。如果您的程序曾经执行过所有操作,则它将永远不会注意到该连接不再存在。
此规则有一些与平台有关的异常(exception),但没有一个涉及远程端点的简单消失。
客户端断开连接的正确方法是使用“关闭”操作正常关闭连接。在.NET中,这意味着客户端代码调用Socket.Shutdown(SocketShutdown.Send)
。然后,客户端必须继续接收,直到服务器调用Socket.Shutdown(SocketShutdown.Both)
为止。请注意,对于启动关闭的端点,关闭“原因”通常为“发送”,对于确认并完成关闭的端点,通常为“两者”。
每个端点都将通过完成将0
作为该操作的字节计数返回值的接收操作来检测到另一端点已关闭其端点。在完成双向平滑关闭之前,任何端点都不应实际关闭套接字(即调用Socket.Close()
)。 IE。每个端点都调用了Socket.Shutdown()
,并且看到了一个零字节的接收操作完成。
上面是正常关闭的工作方式,它应该成为服务器/客户端交互的规范。当然,事情确实会破裂。客户端可能会崩溃,网络可能会断开连接,等等。通常,正确的做法是尽可能长时间地延迟对此类问题的识别;例如,只要服务器和客户端不需要实际通信,那么暂时的网络中断就不会导致错误。在这种情况下,强制一个人是没有意义的。
换句话说,不要添加代码来尝试检测连接失败。为了获得最大的可靠性,让网络尝试自行恢复。
在一些不太常见的情况下,希望尽早检测到连接失败。在这些情况下,您可以在套接字上启用“保持 Activity 状态”(以强制通过连接发送数据,从而检测连接中的中断…请参阅 SocketOptionName.KeepAlive
)或实现某种超时机制(以在没有数据的情况下强制连接失败)在一段时间后发送)。我通常会建议您不要使用这种技术,但是在某些情况下,这是一种有效的方法。
关于c# - 套接字断开通知方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30441394/