(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(暂未测试,下次测试后补上)。

猜你喜欢

转载自www.cnblogs.com/garfield-bc/p/11979044.html