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;
            }
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM