c# socket 心跳 重连

        /// <summary>
        /// 检查一个Socket是否可连接
        /// </summary>
        /// <param name="socket"></param>
        /// <returns></returns>
        private bool IsConnected(Socket socket)
        {
            if (socket == null || socket.Connected == false)
            {
                return false;
            }

            bool blockingState = socket.Blocking;
            try
            {
                byte[] tmp = new byte[1];
                socket.Blocking = false;
                socket.Send(tmp, 0, 0);
                return true;
            }
            catch (SocketException e)
            {
                // 产生 10035 == WSAEWOULDBLOCK 错误,说明被阻止了,但是还是连接的
                if (e.NativeErrorCode.Equals(10035))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            finally
            {
                socket.Blocking = blockingState;    // 恢复状态
            }
        }

上面的代码来自互联网

原理就是在外面加个timer/task/thread,每隔一段时间,做心跳检查。如果发送信息失败表示无法连接,那么我们就可以重连了。

        /// <summary>
        /// 轮询检查Socket连接
        /// </summary>
        private void PollingCheckSocket()
        {
            _pollingCheckSocketTimer = new System.Threading.Timer((obj) =>
            {
                if (!_run)//控制timer暂停、恢复用的
                {
                    return;
                }

                foreach (var hub in _hubs)
                {
                    //为null或断开连接时,重连
                    var connected = this.IsConnected(hub.Socket);
                    if (!connected)
                    {
                        _socketService.Close(hub.Socket);
                        hub.Socket = _socketService.Get(hub);
                    }
                }
            }, null, 10000, 15000);//表示10秒后开始检查,然后每15秒检查一次
        }

我是将socket作为hub的一个属性。这里是遍历所有hub,逐一检查每个hub的socket是否断开。如果断开了,先关闭旧的socket,再重连。需要说明的是,这里的重连是新建一个socket连接,旧的socket连接是无法再次连接的。以下是socket辅助类:

    public class SocketService
    {
        private Logger _logger = LogManager.GetCurrentClassLogger();

        /// <summary>
        /// 获取socket
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public Socket Get(HubModel model)
        {
            try
            {
                // 将IP地址字符串转换为IPAddress对象
                IPAddress ip = IPAddress.Parse(model.IP);
                // 创建终结点EndPoint
                IPEndPoint endPoint = new IPEndPoint(ip, model.Port);
                // 创建Socket并连接到服务器
                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                // 连接到服务器
                socket.Connect(endPoint);

                return socket;
            }
            catch (System.Exception ex)
            {
                _logger.Error(string.Format("获取socket异常,message:{0},stacktrace:{1}", ex.Message, ex.StackTrace));
            }
            return null;
        }

        /// <summary>
        /// 关闭socket
        /// </summary>
        /// <param name="socket"></param>
        public void Close(Socket socket)
        {
            if (socket != null)
            {
                socket.Close();
                socket = null;
            }
        }
    }
}

 

posted @ 2019-10-29 19:07  屌丝大叔的笔记  阅读(5136)  评论(0编辑  收藏  举报