精华内容
下载资源
问答
  • WCF 服务器 客户端 心跳包检测断线 当出现网络问题时,服务器能主动检测到客户端断线,强制它下线。
  • 使用C#实现的TCP客户端,可检测断线(包括网线断开或拔掉),支持断线重连。 对外提供3个事件分别是: 收到数据事件(网络收到数据触发此事件) 通讯空闲事件(长时间无数据收发,时间可设) 重连失败事件(默认最大支持...

    使用C#实现的TCP客户端,可检测断线(包括网线断开或拔掉),支持断线重连。客户端内部有循环缓冲区异步接收数据,对客户端的读操作会立即返回,根据方法返回值来判断读取数据的字节数。

    对外提供3个事件分别是:

    • 收到数据事件(网络收到数据触发此事件)
    • 通讯空闲事件(长时间无数据收发,时间可设)
    • 重连失败事件(默认最大支持3次重连,若3次重连仍然失败则触发事件)

    使用方式:

    //将ReadFromSocket作为线程运行
    private Thread _socketThread;
    private TcpClient _client;
    
    _socketThread = new Thread(_client.ReadFormSocket);
    _socketThread.IsBackground = false;
    _socketThread.Start();
    
    //接收数据操作,除此之外还可以注册接收事件,有数据来时读取
    byte [] recv = new byte[100];
    _client.CommReceive(recv,100);
    
    //发送数据
    byte [] send = new byte[10];
    for (int i = 0; i < 10; i++)
        send[i] = i;
    _client.CommSend(send,10);

    代码实现:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Net.Sockets;
    using System.Net;
    using System.Timers;
    
    namespace Communication
    {
        //通讯接口事件代理
        internal delegate void CommRxEventHandler();
        internal delegate void CommIdleEventHandler();
    
        //通讯接口
        internal interface ICommunication
        {
            event CommRxEventHandler CommRxEvent;       //收到数据事件
            event CommIdleEventHandler CommIdleEvent;   //通讯空闲事件
    
            int CommSend(byte[] buffer, int size);      //发送数据到通讯口
            int CommReceive(CommBuffer buffer);         //从通讯口接收数据
            int CommReceive(byte[] buffer, int size);   //从通讯口接收数据
        }
    
        //TCP客户端实现
        internal class TcpClient : ICommunication
        {
            private const int MAX_RECONNECT_TIMES = 3;  //断线重连尝试次数
            private const int COMM_IDLE_TIMES = 3;      //通讯空闲触发间隔
    
            //soket对象及参数
            private Socket _socket;     
            private string _host;       
            private int _port;
            private bool _reconnect;
            private int ConnecteFailedCount { get; set; }
            public int ReconnectStatistics { get; private set; } 
    
            private static uint _keepAliveTime = 5000;      //无数据交互持续时间(ms)
            private static uint _keepAliveInterval = 500;   //发送探测包间隔(ms)
    
            //定时器,用于触发通讯空闲
            private Timer _timer;
            private int _commIdleCount;
    
            //实现接口的两个事件
            public event CommRxEventHandler CommRxEvent;
            public event CommIdleEventHandler CommIdleEvent;
    
            //重连失败事件
            public event EventHandler ReconnectionFailedEvent;
    
            //数据接收缓存
            private CommBuffer recvBuffer;
    
            //构造函数
            public TcpClient(string host,int port)
            {
                _host = host;
                _port = port;
                _reconnect = false;
                ConnecteFailedCount = 0;
                recvBuffer = new CommBuffer(20480);
            }
            
            //连接
            public void Connect()
            {
                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
                    ProtocolType.Tcp);
                _socket.Connect(_host, _port);
                ConnecteFailedCount = MAX_RECONNECT_TIMES;
    
                //设置KeepAlive
                _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
                byte[] optionValue = new byte[12];
                BitConverter.GetBytes(1).CopyTo(optionValue, 0);
                BitConverter.GetBytes(_keepAliveTime).CopyTo(optionValue, 4);
                BitConverter.GetBytes(_keepAliveInterval).CopyTo(optionValue, 8);
                _socket.IOControl(IOControlCode.KeepAliveValues, optionValue, null);
            }
    
            //重连
            public bool Reconnect()
            {
                ReconnectStatistics++;
                _reconnect = false;
                Close();
                try
                {
                    Connect();
                }
                catch (SocketException e)
                {
                    ConnecteFailedCount--;
                    if (ConnecteFailedCount > 0)
                    {
                        //Console.WriteLine("重试次数剩余{0}",ConnecteFailedCount);
                        _reconnect = true;
                        return true;
                    }
                    else
                    {
                        //重连失败事件
                        if (ReconnectionFailedEvent != null)
                            ReconnectionFailedEvent(this, new EventArgs());
                        return false;
                    }
                }
                return true;
            }
    
            //释放资源
            public void Close()
            {
                _socket.Close();
            }
    
            //启动空闲事件触发
            public void StartCommIdle()
            {
                //定时器配置
                _timer = new Timer(500);
                _timer.AutoReset = true;
                _timer.Elapsed += TimerElapsed;
                _timer.Start();
                _commIdleCount = 0;
            }
            
            //停止空闲事件触发
            public void StopCommIdle()
            {
                _timer.Elapsed -= TimerElapsed;
                _timer.Close();
            }
    
            //发送接收数据事件
            public void SendRecvEvent()
            {
                if (CommRxEvent != null)
                    CommRxEvent();
            }
    
            //发送超时事件
            public void TimerElapsed(object sender, ElapsedEventArgs e)
            {
                if (_commIdleCount++ >= COMM_IDLE_TIMES)
                {
                    if (CommIdleEvent != null)
                        CommIdleEvent();
                    _commIdleCount = 0;
                }
            }
    
            //发送数据接收实现,断线重连
            public int CommSend(byte[] buffer, int size)
            {
                int sendSize = 0;
                try 
                {
                    sendSize = _socket.Send(buffer, size, SocketFlags.None);
                    _commIdleCount = 0;
                }
                catch (SocketException e)
                {
                    ReconnectStatistics++;
                    _reconnect = true;
                }
                return sendSize;
            }
    
            //接收数据接口实现
            public int CommReceive(byte[] buffer, int size)
            {
                return recvBuffer.Read(buffer, size);
            }
    
            //接收数据接口实现
            public int CommReceive(CommBuffer buffer)
            {
                return recvBuffer.CopyTo(buffer);
            }
    
            //接收数据线程,使用阻塞方式接收数据
            public void ReadFormSocket()
            {
                int recvNum;
                byte[] recv = new byte[2048];
                while(true)
                {
                    try
                    {
                        recvNum = _socket.Receive(recv, SocketFlags.None);
                    }
                    catch(SocketException e)
                    {
                        recvNum = 0;
                    }
    
                    //网络断开Receive返回0
                    if (recvNum == 0 || _reconnect == true)
                    {
                        //重连次数用尽,退出
                        if (Reconnect() == false)
                            break;
                    }
                    else
                    {
                        recvBuffer.Write(recv, recvNum);
                        SendRecvEvent();
                    }
                    _commIdleCount = 0;
                }
            }
        }
    
        //通讯缓冲结构类
        internal class CommBuffer
        {
            public uint capacity;              //缓冲区大小
            public int readPtr;                //读指针
            public int writePtr;               //写指针
            public byte[] pBuf;                //缓冲区
     
            //构造函数
            public CommBuffer(uint capacity)
            {
                this.capacity = capacity;
                this.readPtr = 0;
                this.writePtr = 0;
                this.pBuf = new byte[capacity];
            }
     
            //从缓冲区中读取数据到byte数组
            public int Read(byte[] buff, int size)
            {
                int readSize;
                for (readSize = 0; readSize < size; readSize++)
                {
                    if (IsEmpty())
                        break;
                    buff[readSize] = pBuf[readPtr++];
                    if (readPtr >= capacity)
                        readPtr = 0;
                }
                return readSize;
            }
     
            //将byte数组写入缓冲区
            public int Write(byte[] buff, int size)
            {
                int writeSize, wp;
                for (writeSize = 0; writeSize < size; writeSize++)
                {
                    wp = writePtr + 1;
                    if (wp >= capacity)
                        wp = 0;
                    if (wp == readPtr)
                        break;
                    pBuf[writePtr] = buff[writeSize];
                    writePtr = wp;
     
                }
                return writeSize;
            }
     
            //拷贝buffer缓冲区数据到本缓冲区内,会引起拷贝源有效数据为空
            public int Copy(CommBuffer buffer, int len)
            {
                if (len == 0)
                    return 0;
                byte[] data = new byte[len];
                len = buffer.Read(data, len);
                return this.Write(data, len);
            }
     
            //拷贝本缓冲区中的数据到buffer中,会引起拷贝源有效数据为空
            public int CopyTo(CommBuffer buffer)
            {
                int dataLen = this.DataLength();
                if (dataLen == 0)
                    return 0;
                byte[] data = new byte[dataLen];
                dataLen = this.Read(data, dataLen);
                return buffer.Write(data, dataLen);
            }
     
            //索引器实现
            public byte this[int index]
            {
                get
                {
                    if (index >= DataLength())
                        return 0;
                    int rp = readPtr + index;    
                    if (rp >= capacity)
                        rp = rp-(int)capacity;                
                    return pBuf[rp];
                }
            }
     
            //忽略len长度的数据
            public void Skip(int len)
            {
                while (len-- > 0) {
                    if (readPtr == writePtr)
                        break;
                    readPtr++;
                    if (readPtr >= capacity)
                        readPtr = 0;
                }
            }
     
            //判断是否有数据
            public bool IsEmpty()
            {
                return writePtr == readPtr;
            }
     
            //获取有效数据长度
            public int DataLength()
            {
                int len = writePtr-readPtr;
                if (len < 0)
                    len = len + (int)capacity;
                return len;
            }
     
            //清空缓冲区
            public void Clear()
            {
                writePtr = readPtr = 0;
            }
     
            //缓冲区整理,将数据移动到0位置,方便后续数据的处理
            public void Neaten()
            {
                uint i, j;
     
                if (readPtr == 0)
                {
                    return; //读指针已经为0
                }
     
     
                if (readPtr >= writePtr)
                {
                    readPtr = writePtr = 0;
                    return;
                }
     
     
                if (writePtr >= capacity)
                {
                    readPtr = 0;
                    writePtr = 0;
                    return;
                }
     
                i = 0;
                j = (uint)readPtr;
                while (j < writePtr)
                {
                    pBuf[i++] = pBuf[j++];
                }
     
                readPtr = 0;
                writePtr = (int)i;
            }
            //显示缓存数据
            public override string ToString()
            {
                int dataLen = this.DataLength();
                string str = string.Format("数据长度{0}: ", this.DataLength());
                for (int i = 0; i < dataLen; i++)
                {
                    str += string.Format("{0:X} ",this[i]);
                }
                return str;
            }
        }
    }
    

    ps:通讯接口ICommunication用于将各种通讯方式(网络,232串口,485总线等)的接口统一,如此上层应用调用统一接口即可,无需关心实际的通讯介质。对于单独的TCP客户端而言,此处可以跳过,并无实际意义,不喜欢的小伙伴可自行去掉。

    展开全文
  • 心跳包(检测不可检测断线

    千次阅读 2006-11-29 10:19:00
    心跳包(检测不可检测断线) 作者 ricky5266 @ 2006-01-17 09:40:38 一般是用来判断对方(设备,进程或其它网元)是否正常动行,一般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当...

    心跳包(检测不可检测断线)

     

    作者 ricky5266 @ 2006-01-17 09:40:38
    一般是用来判断对方(设备,进程或其它网元)是否正常动行,一般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉。用于检测TCP的异常断开。

    一般是用来判断对方(设备,进程或其它网元)是否正常动行,一般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉。用于检测TCP的异常断开。


    基本原因是服务器端不能有效的判断客户端是否在线也就是说,服务器无法区分客户端是长时间在空闲,还是已经掉线的情况.所谓的心跳包就是客户端定时发送简单的信息给服务器端告诉它我还在而已。

    代码就是每隔几分钟发送一个固定信息给服务端,服务端收到后回复一个固定信息
    如果服务端几分钟内没有收到客户端信息则视客户端断开。比如有些通信软件长时间不使用,要想知道它的状态是在线还是离线就需要心跳包,定时发包收包。

    发包方:可以是客户也可以是服务端,看哪边实现方便合理。一般是客户端。服务器也可以定时轮询发心跳下去。

    一般来说,出于效率的考虑,是由客户端主动向服务器端发包,而不是相反。

     
    展开全文
  • package com.hua; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Scanner; public class ConnectNetWork { /**
    package com.hua;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.util.Scanner;
    
    public class ConnectNetWork {
    	/**
    	 * 执行CMD命令,并返回String字符串
    	 */
    	public static String executeCmd(String strCmd) throws Exception {
    		Process p = Runtime.getRuntime().exec("cmd /c " + strCmd);
    		StringBuilder sbCmd = new StringBuilder();
    		BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), "GB2312"));
    		String line;
    		while ((line = br.readLine()) != null) {
    			sbCmd.append(line + "\n");
    		}
    		return sbCmd.toString();
    
    	}
    
    	/**
    	 * 连接ADSL
    	 */
    	public static boolean connAdsl(String adslTitle, String adslName, String adslPass) throws Exception {
    		System.out.println("正在建立连接.");
    		String adslCmd = "rasdial " + adslTitle + " " + adslName + " " + adslPass;
    		String tempCmd = executeCmd(adslCmd);
    		// 判断是否连接成功
    		if (tempCmd.indexOf("已连接") > 0) {
    			System.out.println("已成功建立连接.");
    			return true;
    		} else {
    			System.err.println(tempCmd);
    			System.err.println("建立连接失败");
    			return false;
    		}
    	}
    
    	/**
    	 * 断开ADSL
    	 */
    	public static boolean cutAdsl(String adslTitle) throws Exception {
    		String cutAdsl = "rasdial " + adslTitle + " /disconnect";
    		String result = executeCmd(cutAdsl);
    
    		if (result.indexOf("没有连接") != -1) {
    			System.err.println(adslTitle + "连接不存在!");
    			return false;
    		} else {
    			System.out.println("连接已断开");
    			return true;
    		}
    	}
    	/**
       * 测试网络是否连接
       */
    	
    	 public static boolean isConnect(){
    	        boolean connect = false;
    	        Runtime runtime = Runtime.getRuntime();
    	        Process process;
    	        try {
    	            process = runtime.exec("ping " + "www.baidu.com");
    	            InputStream is = process.getInputStream(); 
    	            InputStreamReader isr = new InputStreamReader(is); 
    	            BufferedReader br = new BufferedReader(isr); 
    	            String line = null; 
    	            StringBuffer sb = new StringBuffer(); 
    	            while ((line = br.readLine()) != null) { 
    	                sb.append(line); 
    	            } 
    	            System.out.println("返回值为:"+sb);  
    	            is.close(); 
    	            isr.close(); 
    	            br.close(); 
    	 
    	            if (null != sb && !sb.toString().equals("")) { 
    	                String logString = ""; 
    	                if (sb.toString().indexOf("TTL") > 0) { 
    	                    // 网络畅通  
    	                    connect = true;
    	                } else { 
    	                    // 网络不畅通  
    	                    connect = false;
    	                } 
    	            } 
    	        } catch (IOException e) {
    	            e.printStackTrace();
    	        } 
    	        return connect;
    	    }
    
    	 //测试代码
    	public static void main(String[] args) throws InterruptedException,
    	  Exception { Scanner sc = new Scanner(System.in);
    	  System.out.println("宽带连接名称:"); //看你宽带连接的名称
    	  String name = sc.next();
    	  System.out.println("宽带账户:"); 
    	  String username = sc.next();
    	  System.out.println("宽带密码:"); 
    	  String password = sc.next(); 
    	  String adsl= "宽带连接";
    		  while(true){   
    			  boolean connect = isConnect();
    	          Thread.sleep(100000);//单位毫秒,我设置的是100秒.自己看情况更改
    	          if(!connect){
    	        	  System.out.println("无网络,正在重新拨号");
    	              connAdsl(name,username,password);
    	          }
    		  }
    	  
    	}
    }
     /**
       * 自动更换ip
       * */   
     public void changeIp() throws Exception{
        Scanner sc = new Scanner(System.in);
        System.out.println("宽带连接名称:"); // 看你宽带连接的名称
        String name = sc.next();
        System.out.println("宽带账户:");
        String username = sc.next();
        System.out.println("宽带密码:");
        String password = sc.next();
        System.out.println("更换时间(单位毫秒1秒等于1000毫秒):");
        int wait = sc.nextInt();
        while(true){
          connAdsl(name, username, password);
          Thread.sleep(wait);
          cutAdsl(name);
          Thread.sleep(wait);
          //再连,分配一个新的IP
          connAdsl(name, username, password);
        }
        }
    
    
    展开全文
  • 该系统基于TMS320DM642平台,通过对采集的图像进行局部处理,并对局部区域的纱线总数进行统计,最后进行综合判据来检测断线情况。经过大量实验证明,文中设计的视频断线检测系统在检测过程中具有良好的可靠性且效率...
  • 电子政务-步进电机的断线检测装置及断线检测方法.zip
  • 行业分类-物理装置-一种断线检测装置、编码器及其断线检测方法.zip
  • 摘要:为了对纺纱过程进行断线检测和监控,提出基于AT89C2051单片机的纺纱断线检测控制装置,并根据其要求从硬件电路和软件进行了分析设计,从而实现了纺纱断线自动检测,并能在出现断线时控制纺纱机器停止工作,并...
  • 电子政务-可并行检测的电缆断线检测装置.zip
  • 0690、断线检测式报警电路.rar
  • 主要介绍了shell脚本自动检测网络掉线和自动重连,这篇文章介绍的是自动检测连接网络的解决方法,需要的朋友可以参考下
  • websocket封装基于 1.websocket四大基础事件 2.扩展心跳检测断线重连功能 3.核心对象封装,生成与销毁不需要客户端控制
  • 一种WCF检测客户端断线方法

    千次阅读 2016-04-13 15:10:38
    一般检测客户端断线重连的方法都是使用心跳检测。然而增加心跳检测将会稍微影响系统的性能,总之这点资源开销的瑕疵对于有强迫症的我来说有点难接受。在WCF里面其实可以实现客户端断线检测,而不需要心跳。  首先...

           一般检测客户端断线重连的方法都是使用心跳检测。然而增加心跳检测将会稍微影响系统的性能,总之这点资源开销的瑕疵对于有强迫症的我来说有点难接受。在WCF里面其实可以实现客户端断线检测,而不需要心跳。

            首先我要声明,这个方法值适用于WCF服务的会话模式。相信一些资深WCF玩家已经猜到我要说的了。下面我来讲解下

    1、在基于会话模式的WCF服务中,每一个客户端的连接信道都会有一个ID标示,通过它WCF服务可以甄别不同客户端,从而为每个不同客户端创建一个会话通道。

    //这里我们先对契约借口属性进行设置。

             [ServiceContract (CallbackContract = typeof(ICalculatorCallback),SessionMode =SessionMode.Required)]

    2、每一个客户端连接的时候。WCF服务都会创建一个InstanceContext实例上下文,它与客户端同生存周期。每一次创建实例上下文的时候,服务类(就是契约借口的实现类)就会被重新创建(准备的说是重新调用其构造函数)实例消亡时候会自动进行垃圾回收。如下代码:

      [ServiceBehavior(InstanceContextMode =InstanceContextMode.PerSession)]       //在类上方添加服务行为,设置为会话模式。

     public class Service1 : IService1,IDisposable                           //继承IDisposable 借口使得在垃圾回收的时候能够调用Dispose函数
        {
            MessageProperties ms;
            RemoteEndpointMessageProperty remp;                           //这两个变量 用来回去客户端的 地址和端口号。
            public Service1()
            {


                //获取远程端口的IP和端口号。 可以利用来进行心跳检测
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId+"构造器被调用");


                 ms = OperationContext.Current.IncomingMessageProperties;
                 remp = ms[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;


                Console.WriteLine("Get message from " + remp.Address + ":" + remp.Port+"已经连接服务器");

            }


              public void plus(int a, int b)
            {
                //双工通信,调用客户端实现的回调函数。
                ICalculatorCallback callback = OperationContext.Current.GetCallbackChannel<ICalculatorCallback>();   
                callback.showResult(a+b,a,b);
            }


            //如果客户端断开连接,会话就会关闭,实例上下文对象会被释放,从而调用这个函数。这时我们就知道客户端已经断开连接了。

                public void Dispose()
            {
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId +"Dispose方法被调用");
                Console.WriteLine("Get message from " + remp.Address + ":" + remp.Port + "已经离开服务器");
            }


            ~Service1()
            {
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId + "终止化器被调用");
            }

    }

    3. 所为这个检测客户端断线的方式就是看会话通道是否关闭,如果客户端断开连接就会关闭会话垃圾回收机制就会释放实例上下文。只要Dispose函数被调用就说明客户端断开连接。所以有关客户端断线的操作在这个函数里面调用或者设置标识就可以了。

    4.一些运行结果如下所示。

          

    当我禁用本地网络适配器,或者关闭客户端时服务端都能检测到客户端断线并调用Dispose函数 如下



    展开全文
  • socket 断线检测 心跳检测

    千次阅读 2015-03-16 16:44:20
    心跳包:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的...而且逻辑层处理断线
  • 抖音最火火线检测,火线断线检测
  • 摘要:为了对纺纱过程进行断线检测和监控,提出基于AT89C2051单片机的纺纱断线检测控制装置,并根据其要求从硬件电路和软件进行了分析设计,从而实现了纺纱断线自动检测,并能在出现断线时控制纺纱机器停止工作,并...
  • ADC的断线检测功能

    2018-08-01 16:35:36
    转载英飞凌技术交流社区,可用于ADC功能的配置学习,关于断线检测笔者的自己心得。
  • 用户掉线检测

    2014-04-17 13:45:20
    目前主要有三种方法来实现用户掉线检测:SO_KEEPALIVE ,SIO_KEEPALIVE_VALS 和Heart-Beat线程。下面我就上面的三种方法来做一下介绍。一、SO_KEEPALIVE机制这是socket库提供的功能,设置接口是setsockopt API:12...
  • 通过计算主机列表中心跳包到达的时间和检测时间的时间差,如果时间差超过15s,则认为客户端掉线,并将掉线的客户端从主机列表中删除。  由于本文中发送的心跳包为UDP包,所以本文从UDP编程框架、客户端实例和...
  • 行业-电子政务-液晶显示器断线检测电路及检测方法.zip
  • OGW断链检测的可视化方法。 步骤:1. ROI 选择 2. HoG 提取 3. SVM 分类。 确保功能 HoG[1] 和工具箱 Libsvm [2] 已正确安装。 1,利奥(2012年8月)。 定向梯度的直方图。 可在。 ...
  • 行业分类-物理装置-电池断线检测电路.zip
  • 漆包机断线检测仪.zip

    2019-10-21 07:20:24
    漆包机断线检测仪zip,漆包机断线检测
  • 行业资料-电子功用-一种电池断线检测电路及其检测方法
  • 行业-电子政务-断线与短路检测电路.zip
  • 此脚本使用了一个while循环不停的ping被检测设备,如果某一时刻不能收到回包则判定该设备为断线状态,脚本内容如下: #!/bin/bash # Date: 2020-12-23 # Description: CD-office to WAN # Author: fengrui while ...
  • 该代码新增蓝牙断线并重新连接,但是自蓝牙断线检测出的时间为30多秒,有待改进
  • 自动检测多个IP地址,自动检测每个ip记录断线时间,有日志文件
  • netty4.0 心跳检测断线重连操作

    千次阅读 2018-09-25 17:03:14
    那如何实现netty长连接和断线重连呢(网络故障或者其他原因,客户端要无限取重连服务端)。接下来我们看一下如何实现这个两个功能呢。 服务端代码如下: package com.example.nettydemo.demo; import io.netty....
  • TCP断线监测(断线检测

    千次阅读 2013-06-24 11:15:22
    但是非正常的断开,比如直接拔掉了网线,就只能靠如下两种方法,实现短时间内的检测。 一,心跳包机制 心跳包机制,是网游设计中的常用机制。从用户层面,自己发包去判断对方连线状态。可以根据情况,很灵活的使用...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,276
精华内容 6,510
关键字:

如何检测断线