心跳包技术

百度上对于心跳机制的解释是:

    心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制

从字面意思上来看,我们可以知道,它其实在检测socket是否断开的环境下有很大作用,我们就不用担心socket会因为不正常掉线而使得自己的数据丢失了,接下来我们就好好来看看它到底该如何去用

    心跳检测步骤:
      1、客户端每隔一个时间间隔发生一个探测包给服务器
      2、客户端发包时启动一个超时定时器
      3、服务器端接收到检测包,应该回应一个包
      4、如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器
      5、如果客户端的超时定时器超时,依然没有收到应答包,则说明服务器挂了

原理上我们已经搞清楚了,接下来就是具体的实现了

上代码===》》》

客户端:

 1 public class Client {
 2     public static void main(String[] args) {
 3         boolean isSocket = true;
 4         Socket socket = null;
 5         while(isSocket){
 6             try {
 7                 socket = new Socket("192.168.0.174", 30000);
 8                 isSocket = false;
 9                 socket.setKeepAlive(true);   //定期检查两边连接状态
10                 socket.setSoTimeout(10);     //设置超时时间
11                 while (true) {
12                     socket.sendUrgentData(0xFF); // 发送心跳包
13                     System.out.println("处于链接状态!");
14                     Thread.sleep(2 * 1000);//线程睡眠3秒
15                 }
16             } catch (Exception e) {
17                 System.out.println(socket +"");
18                 isSocket = true;
19                 //当连接断开就抛出异常
20                 e.printStackTrace();
21             } 
22         }
23     }
24 }

服务器:

 1 public class Server {
 2     public static void main(String[] args) {
 3         try {
 4             ServerSocket ss = new ServerSocket(30000);
 5             while(true){
 6                 final Socket s = ss.accept();
 7                 // 将请求指定一个线程去执行
 8                 new Thread(new Runnable() {
 9                     public void run() {
10                         try {
11                             Thread.sleep(1 * 1000);
12                         } catch (InterruptedException e) {
13                             e.printStackTrace();
14                         } 
15                     }
16                 }).start();
17             }
18         } catch (Exception e) {
19             e.printStackTrace();
20         }
21     }
22 }

执行结果:

我在客户端给它设置了一个标志位,当发现客户端掉线时会自动再连接上,实现了循环连接循环发送。当然,你也可以在服务器端手动去close掉连接,然后让客户端去连,这就需要你自己去根据下图操作了

但是我们发现了一个问题,当它发送了17次之后,客户端会自动断线,在网上搜素之后发现大家也有这个问题,原因到底是什么呢?

待续...

原文地址:https://www.cnblogs.com/ytlds/p/5661462.html