精华内容
参与话题
问答
  • Socket断线重连

    万次阅读 2018-06-01 11:03:14
    1、当Socket.Conneted == false时,调用如下函数进行判断 /// /// 当socket.connected为false时,进一步确定下当前连接状态 /// /// private bool IsSocketConnected() { #region remarks /****************...

    一、网上常用方法
    1、当Socket.Conneted == false时,调用如下函数进行判断

    ///
    
    /// 当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 = socket.Blocking;
                try
                {
                    byte[] tmp = new byte[1];
    
                    socket.Blocking = false;
                    socket.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
                {
                    socket.Blocking = blockingState;
                }
    
                //Console.WriteLine("Connected: {0}", client.Connected);
                return connectState;
                #endregion
    }
    2、根据socket.poll判断
    点击(此处)折叠或打开
    ///
    
    /// 另一种判断connected的方法,但未检测对端网线断开或ungraceful的情况
    /// 
    /// 
    /// 
    static bool IsSocketConnected(Socket s)
    {
        #region remarks
                /* As zendar wrote, it is nice to use the Socket.Poll and Socket.Available, but you need to take into conside                ration 
                 * that the socket might not have been initialized in the first place. 
                 * This is the last (I believe) piece of information and it is supplied by the Socket.Connected property. 
                 * The revised version of the method would looks something like this: 
                 * from:http://stackoverflow.com/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c */
                #endregion
    
        #region 过程
    
                return !((s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)) || !s.Connected);
    
                /* The long, but simpler-to-understand version:
    
                        bool part1 = s.Poll(1000, SelectMode.SelectRead);
                        bool part2 = (s.Available == 0);
                        if ((part1 && part2 ) || !s.Connected)
                            return false;
                        else
                            return true;
    
                */
                #endregion
    }

    2、根据socket.poll判断

    ///
    
    /// 另一种判断connected的方法,但未检测对端网线断开或ungraceful的情况
    /// 
    /// 
    /// 
    static bool IsSocketConnected(Socket s)
    {
        #region remarks
                /* As zendar wrote, it is nice to use the Socket.Poll and Socket.Available, but you need to take into conside                ration 
                 * that the socket might not have been initialized in the first place. 
                 * This is the last (I believe) piece of information and it is supplied by the Socket.Connected property. 
                 * The revised version of the method would looks something like this: 
                 * from:http://stackoverflow.com/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c */
                #endregion
    
        #region 过程
    
                return !((s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)) || !s.Connected);
    
                /* The long, but simpler-to-understand version:
    
                        bool part1 = s.Poll(1000, SelectMode.SelectRead);
                        bool part2 = (s.Available == 0);
                        if ((part1 && part2 ) || !s.Connected)
                            return false;
                        else
                            return true;
    
                */
                #endregion
    }

    总结:–1–此两种方法出处可在函数体中的remark中找到链接
    –2–此两种方法适用于对端正常关闭socket下的本地socket状态检测,在非正常关闭如断电、拔网线的情况下不起作用
    因为Socket.Conneted存在bug,详见.Net Bugs
    二、支持物理断线重连功能的类

        利用BeginReceive + KeepAlive实现物理断线重连,初步测验了一下,正常。(部分代码参考帖子#26及blog在C#中利用keep-alive处理socket网络异常断开)
        Keep-Alive机制的介绍请看TCP Keepalive HOWTO
        以此备忘,同时希望能帮助到有需要的同学。
    
     using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net.Sockets;
    using System.Net;
    using System.Threading;
    
    namespace MySocket
    {
        public class Socket_wrapper
        {
            //委托
            private delegate void delSocketDataArrival(byte[] data);
            static delSocketDataArrival socketDataArrival = socketDataArrivalHandler;
    
            private delegate void delSocketDisconnected();
            static delSocketDisconnected socketDisconnected = socketDisconnectedHandler;
    
            public static Socket theSocket = null;
            private static string remoteHost = "192.168.1.71";
            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();
    
            ///
    
            /// 构造函数
            /// 
            /// 
            /// 
            public Socket_wrapper(string strIp, int iPort)
            {
                remoteHost = strIp;
                remotePort = iPort;
            }
    
            ///
    
            /// 设置心跳
            /// 
            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
            }
    
            ///
    
            /// 同步receive函数
            /// 
            /// 
            /// 
            public string socket_receive(byte[] readBuffer)
            {
                try
                {
                    if (theSocket == null)
                    {
                        socket_create_connect();
                    }
                    else if (!theSocket.Connected)
                    {
                        if (!IsSocketConnected())
                            Reconnect();
                    }
    
                    int bytesRec = theSocket.Receive(readBuffer);
    
                    if (bytesRec == 0)
                    {
                        //warning 0 bytes received
                    }
                    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;
            }
    
            ///
    
            /// 断线重连函数
            /// 
            /// 
            private static bool Reconnect()
            {
                //关闭socket
                theSocket.Shutdown(SocketShutdown.Both);
    
                theSocket.Disconnect(true);
                IsconnectSuccess = false;
    
                theSocket.Close();
    
                //创建socket
                return socket_create_connect();
            }
    
            ///
    
            /// 当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
            }
    
            ///
    
            /// 另一种判断connected的方法,但未检测对端网线断开或ungraceful的情况
            /// 
            /// 
            /// 
            public static bool IsSocketConnected(Socket s)
            {
                #region remarks
                /* As zendar wrote, it is nice to use the Socket.Poll and Socket.Available, but you need to take into consideration 
                 * that the socket might not have been initialized in the first place. 
                 * This is the last (I believe) piece of information and it is supplied by the Socket.Connected property. 
                 * The revised version of the method would looks something like this: 
                 * from:http://stackoverflow.com/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c */
                #endregion
    
                #region 过程
    
                if (s == null)
                    return false;
                return !((s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)) || !s.Connected);
    
                /* The long, but simpler-to-understand version:
    
                        bool part1 = s.Poll(1000, SelectMode.SelectRead);
                        bool part2 = (s.Available == 0);
                        if ((part1 && part2 ) || !s.Connected)
                            return false;
                        else
                            return true;
    
                */
                #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();
                    }
                }
            }
    
            ///
    
            /// 开始KeepAlive检测函数
            /// 
            private static void StartKeepAlive()
            {
                theSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveCallback), theSocket);
            }
    
            ///
    
            /// BeginReceive回调函数
            /// 
            static byte[] buffer = new byte[1024];
            private static void OnReceiveCallback(IAsyncResult ar)
            {
                try
                {
                    Socket peerSock = (Socket)ar.AsyncState;
                    int BytesRead = peerSock.EndReceive(ar);
                    if (BytesRead > 0)
                    {
                        byte[] tmp = new byte[BytesRead];
                        Array.ConstrainedCopy(buffer, 0, tmp, 0, BytesRead);
                        if (socketDataArrival != null)
                        {
                            socketDataArrival(tmp);
                        }
                    }
                    else//对端gracefully关闭一个连接
                    {
                        if (theSocket.Connected)//上次socket的状态
                        {
                            if (socketDisconnected != null)
                            {
                                //1-重连
                                socketDisconnected();
                                //2-退出,不再执行BeginReceive
                                return;
                            }
                        }
                    }
                    //此处buffer似乎要清空--待实现 zq
                    theSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(OnReceiveCallback), theSocket);
                }
                catch (Exception ex)
                {
                    if (socketDisconnected != null)
                    {
                        socketDisconnected(); //Keepalive检测网线断开引发的异常在这里捕获
                        return;
                    }
                }
            }
    
            ///
    
            /// 异步收到消息处理器
            /// 
            /// 
            private static void socketDataArrivalHandler(byte[] data)
            {
            }
    
            ///
    
            /// socket由于连接中断(软/硬中断)的后续工作处理器
            /// 
            private static void socketDisconnectedHandler()
            {
                Reconnect();
            }
    
            ///
    
            /// 检测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 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;
            }
        }
    }   
    展开全文
  • android java socket断线重连 thread = new Thread(new Runnable() { @Override public void run() { while (true){ boolean close = isServerClose(socket);//判断是否断开 ...

    android java socket断线重连

    thread = new Thread(new Runnable()
    {
        @Override
        public void run()
        {
    
            while (true){
                boolean close = isServerClose(socket);//判断是否断开
                if(close){//没有断开,开始读数据;
                    try
                    {
                        Log.d(TAG, "ZYF ip"+getIp());
                        socket = new Socket(getIp(),10801); //创建Socket实例,并绑定连接远端IP地址和端口
                        Log.d(TAG,"ZYF SOCKET 创建成功!");
                        Message msg = new Message();
                        msg.what = TOAST_TRUE;
                        handler.sendMessage(msg);
                        SocketReceiveImgAndVideoFromServer();
                    }
                    catch (IOException e)
                    {
                        Message msg = new Message();
                        msg.what = TOAST_FAILE;
                        handler.sendMessage(msg);
                        e.printStackTrace();
                    }
                    try {
                        Thread.sleep(5000);//五秒判断一次
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }

    点击并拖拽以移动

    Looper.prepare();
    Looper.loop();// 进入loop中的循环,查看消息队列

    千万别乱用这个,这个能让线程堵塞!!!!!!!!!!!!!!!

    转载于:https://www.cnblogs.com/zx125/p/11490408.html

    展开全文
  • c# socket 断线重连

    千次阅读 2019-02-14 17:53:57
    里面有socket的封装类 ...服务器端主动断开连接,客户端会抛出异常,并会设置连接状态 IsconnectSuccess 为false,但不会自动重连,所以加了一个timer Socket_wrapper.remoteHost="127.0...

    https://blog.csdn.net/thebestleo/article/details/52354126

    里面有socket的封装类

    但是没有使用的代码,在这里补充一下

    服务器端主动断开连接,客户端会抛出异常,并会设置连接状态 IsconnectSuccess 为false,但不会自动重连,所以加了一个timer

    Socket_wrapper.remoteHost="127.0.0.1";
                Socket_wrapper.remotePort = 9601;
                Socket_wrapper.checkSocketState();
    
                timer = new Timer();
                timer.Interval = 30 * 1000;
                timer.Tick += Timer_Tick;
                timer.Start();
    private void Timer_Tick(object sender, EventArgs e)
            {
                Socket_wrapper.checkSocketState();
            }

     

    展开全文
  • 有三个字典Dic比较重要 socket - account account - socket account - 游戏数据 ...如果想断线重连后,取回之前产生的数据,就要用account去取 FR:徐海涛(Hunk Xu) QQ技术交流群:386476712

    有三个字典Dic比较重要

    socket - account

    account - socket

    account - 游戏数据


    如果想断线重连后,取回之前产生的数据,就要用account去取


     

     

    FR:徐海涛(Hunk Xu)
    QQ技术交流群:386476712

    展开全文
  • 自己写的源码,请拿去用!
  • C#之Socket断线重连

    2018-11-12 10:49:00
    1、当Socket.Conneted == false时,调用如下函数进行判断 /// /// 当socket.connected为false时,进一步确定下当前连接状态 /// /// private bool IsSocketConnected() { #region remarks /**********...
  • asyncio.Protocol socket 断线重连  原文:https://www.jianshu.com/p/f5bc755d3d8a 场景 使用asyncio.Protocol进行异步连接时,如何断线重连 code socket client 放在了单独的一个线程中soket_server.py ...
  • 之前从teamtalk的核心库里面剥离出一个跨平台网络库,一开始用的好好的,可是在某些地方使用的时候总是出怪问题,有时候断线重连就一直连不上,导致应用失联,在实际使用场景中一直出问题,好不尴尬。 经过连三天的...
  • Socket 断线重连问题

    万次阅读 2016-09-22 14:10:31
    关于断线重连的思路大概如下 当与服务器断开连接或网络出错时,先不要处理当前正在连接的socket,可能回应下当前UI的数据显示问题; 可以另起一个socket服务,与服务器尝试连接,当连接成功时,通知当前Socket进行...
  • C# 判断Socket断线重连

    千次阅读 2017-05-04 14:03:47
    定时器里面的事件 private ... // 首先,Socket类的Connected属性只表示最后一次I/O操作的状态,如果这之后[连接的另一方]断开了,它还一直返回true, 除非你再通过socket来发送数据。所以通过个属性来判断是行不通的!
  • C# + Socket断线重连

    2017-02-15 15:50:49
    C# + Socket断线重连 2013-07-09 10:37:39 http://59949.htmlfyxspgpw.blog.chinaunix.net/uid-28765492-id-3793532.html 分类: C#/.net 一、网上常用方法 1、当Socket.Conneted == false...
  • 1.创建 static dispatch_source_t _reconTimer; dispatch_source_cancel(_timer);  NSTimeInterval period = 5; //设置时间间隔  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE
  • C# + Socket断线重连 整理

    万次阅读 2016-05-15 21:56:35
    1、当Socket.Conneted == false时,调用如下函数进行判断 点击(此处)折叠或打开 /// /// 当socket.connected为false时,进一步确定下当前连接状态 ///  ///  private bool IsSocketConnected() {  #...
  • 其中,第1个第2个都已经解决,针对第3个问题,我的客户端检测到断开后,一直循环重连直到再次连接上,但是实际情况上,客户端的循环要多执行一次,每次都会导致连接上2个,同一个IP不同的端口(其实只有一个客户端)...

空空如也

1 2 3 4 5 ... 12
收藏数 238
精华内容 95
关键字:

socket断线重连