心跳机制
来源:互联网 发布:数据地区分布图怎么做 编辑:程序博客网 时间:2024/05/01 23:52
心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制。
大部分CS的应用需要心跳机制。心跳机制一般在Server和Client都要实现,两者实现原理基本一样。Client不关心性能,怎么做都行。
如果应用是基于TCP的,可以简单地通过SO_KEEPALIVE实现心跳。TCP在设置的KeepAlive定时器到达时向对端发一个检测TCP segment,如果没收到ACK或RST,尝试几次后,就认为对端已经不存在,最后通知应用程序。这里有个缺点是,Server主动发出检测包,对性能有点影响。
应用自己实现
Client启动一个定时器,不断发心跳;
Server收到心跳后,给个回应;
Server启动一个定时器,判断Client是否存在,判断方法这里列两种:
时间差和简单标志。
时间差策略
收到一个心跳后,记录当前时间(记为recvedTime)。
判断定时器时间到达,计算多久没收到心跳的时间(T)=当前时间 - recvedTime(上面记录的时间)。如果T大于某个设定值,就可以认为Client超时了。
简单标志
收到一个心跳后,设置连接标志为true;
判断定时器时间到达,查看所有的标志,false的,认为对端超时了;true的将其设成false。
上面这种方法比上面简单一些,但检测某个Client是否离线的误差有点大。
Demo
此处我们实现一个发送对象,例子简陋,实际在工作中还需按需求修改。
实体类
package com.lee.entity;
import java.io.Serializable;
public class Entity implements Serializable {
private static final long serialVersionUID = 1L;private String name;private String sex;public String getName() { return name;}public void setName(String name) { this.name = name;}public String getSex() { return sex;}public void setSex(String sex) { this.sex = sex;}@Overridepublic String toString() { return "Entity [name=" + name + ", sex=" + sex + "]";}
}
1
服务端
ServerHeart.java
package com.lee.server;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import com.lee.entity.Entity;
public class ServerHeart extends Thread {
private ServerSocket server = null;Object obj = new Object();@Overridepublic void run() { try { server = new ServerSocket(9090); while (true) { Socket client = server.accept(); synchronized (obj) { new Thread(new Client(client)).start(); } } } catch (Exception e) { e.printStackTrace(); }}/** * 客户端线程 * * @author USER * */class Client implements Runnable { Socket client; public Client(Socket client) { this.client = client; } @Override public void run() { try { while (true) { ObjectInput in = new ObjectInputStream(client.getInputStream()); Entity entity = (Entity) in.readObject(); System.out.println(entity); } } catch (Exception e) { e.printStackTrace(); } }}/** * 程序的入口main方法 * * @param args */public static void main(String[] args) { System.out.println("开始检测客户端是否在线..."); new ServerHeart().start();}
}
1
客户端
ClientHeart.java
package com.lee.client;
public class ClientHeart extends Thread {
@Overridepublic void run() { try { while (true) { ClientSender.getInstance().send(); synchronized (ClientHeart.class) { // this.wait(5000); Thread.sleep(2000); } } } catch (Exception e) { e.printStackTrace(); }}/** * 程序的入口main方法 * * @param args */public static void main(String[] args) { ClientHeart client = new ClientHeart(); client.start();}
}
1
ClientSender.java
package com.lee.client;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import com.lee.entity.Entity;
public class ClientSender {
private ClientSender() {}Socket sender = null;private static ClientSender instance;public static ClientSender getInstance() { if (instance == null) { synchronized (ClientHeart.class) { instance = new ClientSender(); } } return instance;}public void send() { try { sender = new Socket(InetAddress.getLocalHost(), 9090); while (true) { ObjectOutputStream out = new ObjectOutputStream(sender.getOutputStream()); Entity obj = new Entity(); obj.setName("xiaoming"); obj.setSex("男"); out.writeObject(obj); out.flush(); System.out.println("已发送..."); Thread.sleep(5000); } } catch (Exception e) { }}
}
1
- 心跳机制
- 心跳机制
- 心跳机制
- 心跳机制
- 心跳机制
- 心跳机制
- 心跳机制
- 心跳机制
- 心跳包机制
- hadoop心跳机制解析
- TCP心跳机制
- 心跳包机制
- Socket心跳包机制
- Socket心跳包机制
- hadoop心跳机制解析
- 微信-心跳机制
- IdTCPClient / IdTCPServer + 心跳机制
- socket 心跳包机制
- 如何提交测试任务
- CentOS下安装nginx服务器
- Mule SEDA
- 出生年(15分)
- STM32系统结构、时钟树
- 心跳机制
- Android 6.0 权限的添加
- 逆向工程核心原理学习笔记(八):小端序标记法1
- 继续dropout
- Java多线程之synchronized的使用技巧
- Eclipse项目Module3.0错误
- 逆向工程核心原理学习笔记(九):小端序标记法2
- Java8中的日期时间
- 为什么有些语言可以被反编译?而有的不能?