• TCP自动重连


    网上模板:

        public class Socket_wrapper
        {
            public static Socket theSocket = null;
            private static string remoteHost = "192.168.1.14";
            private static int remotePort = 6666;
    
            private static String SockErrorStr = null;
            private static ManualResetEvent TimeoutObject = new ManualResetEvent(false);
            private static Boolean IsconnectSuccess = false; //异步连接情况,由异步连接回调函数置位  
            private static object lockObj_IsConnectSuccess = new object();
    
            /// 设置心跳  
            ///   
            private static void SetXinTiao()
            {
                //byte[] inValue = new byte[] { 1, 0, 0, 0, 0x20, 0x4e, 0, 0, 0xd0, 0x07, 0, 0 };// 首次探测时间20 秒, 间隔侦测时间2 秒  
                byte[] inValue = new byte[] { 1, 0, 0, 0, 0x88, 0x13, 0, 0, 0xd0, 0x07, 0, 0 };// 首次探测时间5 秒, 间隔侦测时间2 秒  
                theSocket.IOControl(IOControlCode.KeepAliveValues, inValue, null);
            }
    
            /// 创建套接字+异步连接函数  
            ///   
            ///   
            private static bool socket_create_connect()
            {
                IPAddress ipAddress = IPAddress.Parse(remoteHost);
                IPEndPoint remoteEP = new IPEndPoint(ipAddress, remotePort);
                theSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                theSocket.SendTimeout = 1000;
    
                SetXinTiao();//设置心跳参数  
    
                #region 异步连接代码
    
                TimeoutObject.Reset(); //复位timeout事件  
                try
                {
                    theSocket.BeginConnect(remoteEP, connectedCallback, theSocket);
                }
                catch (Exception err)
                {
                    SockErrorStr = err.ToString();
                    return false;
                }
                if (TimeoutObject.WaitOne(10000, false))//直到timeout,或者TimeoutObject.set()  
                {
                    if (IsconnectSuccess)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    SockErrorStr = "Time Out";
                    return false;
                }
                #endregion
            }
    
            /// 异步连接回调函数  
            ///   
            ///   
            static void connectedCallback(IAsyncResult iar)
            {
                #region <remarks>
                /// 1、置位IsconnectSuccess  
                #endregion </remarks>
    
                lock (lockObj_IsConnectSuccess)
                {
                    Socket client = (Socket)iar.AsyncState;
                    try
                    {
                        client.EndConnect(iar);
                        IsconnectSuccess = true;
                        //StartKeepAlive(); //开始KeppAlive检测  
                    }
                    catch (Exception e)
                    {
                        //Console.WriteLine(e.ToString());  
                        SockErrorStr = e.ToString();
                        IsconnectSuccess = false;
                    }
                    finally
                    {
                        TimeoutObject.Set();
                    }
                }
            } 
    
            /// 同步receive函数  
            ///   
            ///   
            ///   
            public string socket_receive(byte[] readBuffer)
            {
                while (true)
                {
                    try
                    {
                        if (theSocket == null)
                        {
                            if (!socket_create_connect())
                            {
                                Thread.Sleep(1000);
                                continue;
                            }
                        }
                        else if (!theSocket.Connected)
                        {
                            if (!IsSocketConnected())
                                if (!Reconnect())
                                {
                                    Thread.Sleep(1000);
                                    continue;
                                }
                        }
    
                        int bytesRec = theSocket.Receive(readBuffer);
    
                        if (bytesRec == 0)
                        {
                            //warning 0 bytes received
                            if (!Reconnect())
                            {
                                Thread.Sleep(1000);
                                continue;
                            }
                        }
                        return Encoding.ASCII.GetString(readBuffer, 0, bytesRec);
                    }
                    catch (SocketException se)
                    {
                        //print se.ErrorCode  
                        throw;
                    }
                }
            }
    
            /// 同步send函数  
            ///   
            ///   
            ///   
            public bool socket_send(string sendMessage)
            {
                if (checkSocketState())
                {
                    return SendData(sendMessage);
                }
                return false;
            }
    
            /// 同步发送  
            ///   
            ///   
            ///   
            public static bool SendData(string dataStr)
            {
                bool result = false;
                if (dataStr == null || dataStr.Length < 0)
                    return result;
                try
                {
                    byte[] cmd = Encoding.Default.GetBytes(dataStr);
                    int n = theSocket.Send(cmd);
                    if (n < 1)
                        result = false;
                }
                catch (Exception ee)
                {
                    SockErrorStr = ee.ToString();
                    result = false;
                }
                return result;
            }
    
            /// 当socket.connected为false时,进一步确定下当前连接状态  
            ///   
            ///   
            private bool IsSocketConnected()
            {
                #region remarks
                /******************************************************************************************** 
                 * 当Socket.Conneted为false时, 如果您需要确定连接的当前状态,请进行非阻塞、零字节的 Send 调用。 
                 * 如果该调用成功返回或引发 WAEWOULDBLOCK 错误代码 (10035),则该套接字仍然处于连接状态;  
                 * 否则,该套接字不再处于连接状态。 
                 * Depending on http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.connected.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2 
                ********************************************************************************************/
                #endregion
    
                #region 过程
                // This is how you can determine whether a socket is still connected.  
                bool connectState = true;
                bool blockingState = theSocket.Blocking;
                try
                {
                    byte[] tmp = new byte[1];
    
                    theSocket.Blocking = false;
                    theSocket.Send(tmp, 0, 0);
                    //Console.WriteLine("Connected!");  
                    connectState = true; //若Send错误会跳去执行catch体,而不会执行其try体里其之后的代码  
                }
                catch (SocketException e)
                {
                    // 10035 == WSAEWOULDBLOCK  
                    if (e.NativeErrorCode.Equals(10035))
                    {
                        //Console.WriteLine("Still Connected, but the Send would block");  
                        connectState = true;
                    }
    
                    else
                    {
                        //Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);  
                        connectState = false;
                    }
                }
                finally
                {
                    theSocket.Blocking = blockingState;
                }
    
                //Console.WriteLine("Connected: {0}", client.Connected);  
                return connectState;
                #endregion
            }
    
            /// 断线重连函数  
            ///   
            ///   
            private static bool Reconnect()
            {
                //关闭socket  
                theSocket.Shutdown(SocketShutdown.Both);
    
                theSocket.Disconnect(true);
                IsconnectSuccess = false;
    
                theSocket.Close();
    
                //创建socket  
                return socket_create_connect();
            }
    
            /// 检测socket的状态  
            ///   
            ///   
            public static bool checkSocketState()
            {
                try
                {
                    if (theSocket == null)
                    {
                        return socket_create_connect();
                    }
                    else if (IsconnectSuccess)
                    {
                        return true;
                    }
                    else//已创建套接字,但未connected  
                    {
                        #region 异步连接代码
    
                        TimeoutObject.Reset(); //复位timeout事件  
                        try
                        {
                            IPAddress ipAddress = IPAddress.Parse(remoteHost);
                            IPEndPoint remoteEP = new IPEndPoint(ipAddress, remotePort);
                            theSocket.BeginConnect(remoteEP, connectedCallback, theSocket);
    
                            SetXinTiao();//设置心跳参数  
                        }
                        catch (Exception err)
                        {
                            SockErrorStr = err.ToString();
                            return false;
                        }
                        if (TimeoutObject.WaitOne(2000, false))//直到timeout,或者TimeoutObject.set()  
                        {
                            if (IsconnectSuccess)
                            {
                                return true;
                            }
                            else
                            {
                                return false;
                            }
                        }
                        else
                        {
                            SockErrorStr = "Time Out";
                            return false;
                        }
    
                        #endregion
                    }
    
                }
                catch (SocketException se)
                {
                    SockErrorStr = se.ToString();
                    return false;
                }
            } 
        }

    个人简化改进:

     public void SocketCreateConnect()
            {
                try
                {
                    tcpClient = new TcpClient(localEP);
                    tcpClient.BeginConnect(remoteEP.Address, remoteEP.Port, ConnectedCallback, tcpClient);
                }
                catch
                { }
    
            }
    
            /// 异步连接回调函数  
            ///   
            /// 
            private void ConnectedCallback(IAsyncResult iar)
            {
                #region <remarks>
                /// 1、置位IsconnectSuccess  
                #endregion </remarks>
    
                lock (lockObj_IsConnectSuccess)
                {
                    TcpClient tcpClient = (TcpClient)iar.AsyncState;
                    try
                    {
                        tcpClient.EndConnect(iar);
                        //IsconnectSuccess = true;
                        Receive_Radar29();
                    }
                    catch (Exception e)
                    {
                        //IsconnectSuccess = false;
                        Thread.Sleep(10000);
                        tcpClient.BeginConnect(remoteEP.Address, remoteEP.Port, ConnectedCallback, tcpClient);
                    }
                }
            }
    
            /// 当socket.connected为false时,进一步确定下当前连接状态  
            ///   
            ///   
            private bool IsSocketConnected()
            {
                #region remarks
                /******************************************************************************************** 
                 * 当Socket.Conneted为false时, 如果您需要确定连接的当前状态,请进行非阻塞、零字节的 Send 调用。 
                 * 如果该调用成功返回或引发 WAEWOULDBLOCK 错误代码 (10035),则该套接字仍然处于连接状态;  
                 * 否则,该套接字不再处于连接状态。 
                 * Depending on http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.connected.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2 
                ********************************************************************************************/
                #endregion
    
                #region 过程
                // This is how you can determine whether a socket is still connected.  
                bool connectState = true;
                bool blockingState = tcpClient.Client.Blocking;
                try
                {
                    byte[] tmp = new byte[1];
    
                    tcpClient.Client.Blocking = false;
                    tcpClient.Client.Send(tmp, 0, 0);
                    //Console.WriteLine("Connected!");  
                    connectState = true; //若Send错误会跳去执行catch体,而不会执行其try体里其之后的代码  
                }
                catch (SocketException e)
                {
                    // 10035 == WSAEWOULDBLOCK  
                    if (e.NativeErrorCode.Equals(10035))
                    {
                        //Console.WriteLine("Still Connected, but the Send would block");  
                        connectState = true;
                    }
    
                    else
                    {
                        //Console.WriteLine("Disconnected: error code {0}!", e.NativeErrorCode);  
                        connectState = false;
                    }
                }
                finally
                {
                    tcpClient.Client.Blocking = blockingState;
                }
    
                //Console.WriteLine("Connected: {0}", client.Connected);  
                return connectState;
                #endregion
            }
    
            /// 断线重连函数  
            ///   
            ///   
            private void Reconnect()
            {
                //IsconnectSuccess = false;
    
                tcpClient.Close();
                streamToServer.Close();
    
                //创建socket  
                SocketCreateConnect();
            }
    
            private void Receive_Radar29()
            {
                buffer = new byte[BufferSize];
                while (true)
                {
                    try
                    {
                        if (!tcpClient.Client.Connected)
                        {
                            if (!IsSocketConnected())
                            {
                                Reconnect();
                                return;
                            }
                        }
    
                        streamToServer = tcpClient.GetStream();
                        int count = streamToServer.Read(buffer, 0, BufferSize);
                        if (count == 0)
                        {
                            Reconnect();
                            return;
                        }
                        temp_buffer = new byte[count];
                        Array.Copy(buffer, 0, temp_buffer, 0, temp_buffer.Length);
                        Array.Clear(buffer, 0, buffer.Length);
                        List<byte[]> protocolList = requestHandler.GetActualProtocolByte(temp_buffer.ToList());
                        foreach (var item in protocolList)
                        {
                            Task.Factory.StartNew(ProcessProtocol, item);
                            //ProcessProtocol(item);
                        }
                    }
                    catch
                    {
                        //if (streamToServer != null)
                        //{
                        //    streamToServer.Close();
                        //}
                        //tcpClient.Close();
                        //break;
                        continue;
                    }
                }
            }
  • 相关阅读:
    运行hexo提示/usr/bin/env: node: 没有那个文件或目录
    安装cuda时 提示toolkit installation failed using unsupported compiler解决方法
    使用caffe自动测试模型top5的结果
    配置caffe的python环境时make pycaffe提示fatal error: numpy/arrayobject.h No such file or directory解决方法
    error: library dfftpack has Fortran sources but no Fortran compiler found解决方法
    ubuntu硬盘安装卡在探测文件系统
    win7+ubuntu双系统中卸载ubuntu方法
    深度学习入门教程UFLDL学习实验笔记三:主成分分析PCA与白化whitening
    深度学习入门教程UFLDL学习实验笔记二:使用向量化对MNIST数据集做稀疏自编码
    深度学习入门教程UFLDL学习实验笔记一:稀疏自编码器
  • 原文地址:https://www.cnblogs.com/liuslayer/p/9438398.html
Copyright © 2020-2023  润新知