我在不同计算机上的C#,服务器和客户端程序中用c / s模式编写了一个comunication程序。今天客户端程序连接到服务器progarm后,我从网络适配器拔出电缆(此后,客户端和服务器程序没有做任何事情),发生了奇怪的事情。我发现服务器程序的socket仍然保持连接状态。我使用命令“netstat -a -n”来检索网络信息,并获得如下信息:
TCP 192.168.1.2:3645 192.168.1.3:1863 ESTABLISHED
192.168.1.2(服务器IP地址) 192.168.1.3(客户端IP地址)
有谁知道原因?如何解决这个问题呢 。 我想知道服务器程序如何接收事件并在拔出客户端计算机的网络电缆时关闭套接字。
请给我一些建议或解决方案。
由于
答案 0 :(得分:5)
我认为可以通过使用TCP keepalive来解决。 refrence http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html
连接后,设置socket keepalive属性。 msdn说这个开关默认状态是关闭的,如果将keepalive设置为on,socket会自动检查网络状态,并且在socket上次操作后首先检查时间是2小时。但时间可以缩短。然后在第一次检查后,套接字将服务时间。如果连接中断或死亡, socket会抛出异常。
C#来源:
uint dummy = 0;
byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
//set keepalive on
BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0);
//interval time between last operation on socket and first checking. example:5000ms=5s
BitConverter.GetBytes((uint)5000).CopyTo(inOptionValues, Marshal.SizeOf(dummy));
//after first checking, socket will check serval times by 1000ms.
BitConverter.GetBytes((uint)1000).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);
Socket socket = __Client.Client;
socket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);
我已经查过了。它运行正常。
答案 1 :(得分:3)
你做不到。 检查连接状态的唯一可靠方法是通过线路发送数据,因此:处理发送/接收期间的连接失败,并且,如果您希望在空闲期间连接状态,可选择通过某种形式的ping定期检查连接状态
答案 2 :(得分:-1)
我有点不确定,但是如果你在拔完电缆后尝试从插座中读取数据,它会告诉你它已经不再连接了..