我在不同的计算机上用C#,服务器和客户端程序编写了一个带c/s模式的通信程序.今天客户端程序连接到服务器progarm后,我从网络适配器拔出电缆(此后,客户端和服务器程序没有做任何事情),发生了奇怪的事情.我发现服务器程序的socket仍然保持连接状态.我使用命令"netstat -a -n"来检索网络信息,并获得如下信息:
TCP 192.168.1.2:3645 192.168.1.3:1863已建立
192.168.1.2(服务器IP地址)192.168.1.3(客户端IP地址)
有人知道原因吗?如何解决这个问题呢 .我想知道服务器程序如何接收事件并在拔出客户端计算机的网络电缆时关闭套接字.
请给我一些建议或解决方案.
谢谢
我认为可以通过使用TCP keepalive来解决.参考http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html
连接后,设置socket keepalive属性.msdn说这个开关默认状态是关闭的,如果将keepalive设置为on,socket会自动检查网络状态,并且在socket上次操作后首先检查时间是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);
Run Code Online (Sandbox Code Playgroud)
我检查过.它运行正常.