(C# TCP异步)客户端异常断开,服务器利用KeepAlive监测


最近在做的项目是用C#作服务端,客户端每隔10秒发起一次连接,出现的问题是:由于同学在做的客户端侧有一些bug暂未解决,经常会出现客户端崩掉,但服务端却没有监测到socket异常断开。

查了资料后发现有两种方式可以解决:

1、用心跳包方式(服务端每隔几秒向客户端发起请求,如果没有收到客户端回应,则判定为客户端下线)

2、用socket的KeepAlive机制(个人感觉和心跳包有点类似)

 

我先用了心跳包的方式测试,发现虽然确实可以将对应的socket关闭,但是延迟很大(在建立socket连接后,把客户端断网5s-20s,服务器才会断开其socket连接),所以选择使用KeepAlive机制。

 

Socket server;

//server绑定端口及监听就不贴出来了

Socket client = server.Accept();

client.IOControl(IOControlCode.KeepAliveValues, KeepAlive(1, 3000, 500), null);//设置Keep-Alive参数
  
private byte[] KeepAlive(int onOff, int keepAliveTime, int keepAliveInterval)
{
        uint dummy = 0;
        byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
        BitConverter.GetBytes((uint)onOff).CopyTo(inOptionValues, 0);
        BitConverter.GetBytes((uint)keepAliveTime).CopyTo(inOptionValues, Marshal.SizeOf(dummy));//keep-alive间隔(单位ms)
        BitConverter.GetBytes((uint)keepAliveInterval).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);// 尝试间隔(单位ms)
        return inOptionValues;
}

 

  

设置完以后,还需要在Receive的异步回调函数的catch里执行客户端socket的close方法(try里执行EndReceive或者下一次的BeginReceive)。

不过使用TcpClient的话好像无需在Receive的异步回调函数里手动执行close(暂未测试,下次测试后补上)。

 

 

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM