C#的TCP/IP通讯中,断线重连是一个基础必备的功能,之前比较喜欢用心跳帧来做断线重连,简单又方便。
但是事情往往并不是都能如我们所愿,比如在最近的一个项目中,碰到一个傻逼Server,不支持异步,不能使用心跳帧,之前的断线重连功能就KeepDie了,嘤嘤嘤。。。
不过办法总比问题多,经过不懈的Google,终于找到一种根据本地计算机(支持TCPClient的IO操作)网络状态来判断是否断线,并且可以实现完美的KeepAlive。
下面是关键代码:
server = ip.Text;
Port =Convert.ToInt32( this.port.Text);
tcpclient = new TcpClient(server, Port);
// 启用keep-alive
tcpclient.Client.IOControl(IOControlCode.KeepAliveValues, GetKeepAliveData(), null);
tcpclient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.UTF8.GetBytes("连接开始 发送第一个数据");
// Get a client stream for reading and writing.
// Stream stream = client.GetStream();
NetworkStream stream = tcpclient.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
private byte[] GetKeepAliveData()
{
uint dummy = 0;
byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0);
BitConverter.GetBytes((uint)3000).CopyTo(inOptionValues, Marshal.SizeOf(dummy));//keep-alive间隔
BitConverter.GetBytes((uint)500).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);// 尝试间隔
return inOptionValues;
}
下面是效果展示:
关闭服务器连接:
一段时间之后打开服务器:
话不多说,直接DEMO