2011-01-11 87 views
1

我在C#,服务器和客户端程序中使用c/s模式在不同计算机上编写通信程序。今天客户端progarm连接到服务器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

记住,socket.Connected(或IsConnected,我忘了)只会告诉你最后一个命令后的套接字状态。所以如果你最后的命令成功了,它将返回true。如果你拔出电缆,它将继续是真实的,直到你尝试使用它,并有什么失败。 – NibblyPig 2011-01-11 16:01:45

回答

4

我认为这可以通过使用TCP keepalive来解决。 refrence http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html

连接后,设置套接字keepalive属性。 msdn说这个开关的默认状态是关闭的,如果设置保持打开,套接字将自动检查网络状态,并且首先检查时间是在最后一次对套接字进行操作后2小时。但时间可以缩短。然后在第一次检查后,套接字将会保留时间。如果连接断开或者死亡, 套接字将抛出异常。

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

我是个有点不确定,但如果您尝试拉电缆后从套接字读取数据时,它会告诉你,它没有连接任何更多..

+0

非常感谢。但我想赶上这个例外。因为程序业务是:服务器向客户端发送命令,并且clinet接收命令并执行它然后发回结果。服务器接收程序是异步的,所以当我拔掉电缆时,服务器无法收到任何数据。 – user571102 2011-01-11 15:43:33

+0

没有一些代码我不能帮你..但你必须在听数据,这应该去的时候,电缆拉... – Peter 2011-01-11 15:52:33

2

你不能。 检查连接状态的唯一可靠方法是通过线路发送数据,因此:处理发送/接收期间的连接失败,以及可选地,通过某种形式的ping定期检查连接状态,如果您希望在闲置时连接状态周期。