Java的Socket通信完整实例(心跳包,客户端断线重连,服务端超时断开客户端连接)的客户端和服务端
时间: 2023-11-03 15:04:15 浏览: 169
好的,下面是 Java Socket 通信的完整实例,包含心跳包、客户端断线重连和服务端超时断开客户端连接的实现。
服务端代码:
```java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server {
private static final int PORT = 8888;
private static final int TIMEOUT = 5000; // 服务端超时时间
private static final String HEARTBEAT_MSG = "ping"; // 心跳包内容
private ServerSocket serverSocket;
private List<Socket> clientList = new ArrayList<>();
private ExecutorService executorService = Executors.newCachedThreadPool();
public Server() {
try {
serverSocket = new ServerSocket(PORT);
System.out.println("服务端已启动,监听端口:" + PORT);
while (true) {
Socket socket = serverSocket.accept();
clientList.add(socket);
executorService.execute(new ClientHandler(socket));
}
} catch (IOException e) {
e.printStackTrace();
}
}
private class ClientHandler implements Runnable {
private Socket socket;
private OutputStream outputStream;
public ClientHandler(Socket socket) {
this.socket = socket;
try {
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[1024];
int len;
boolean isRunning = true;
long lastReceiveTime = System.currentTimeMillis();
while (isRunning) {
// 接收数据
if ((len = inputStream.read(buffer)) != -1) {
String receiveMsg = new String(buffer, 0, len);
System.out.println("服务端接收到消息:" + receiveMsg);
if (HEARTBEAT_MSG.equals(receiveMsg)) { // 心跳包消息
outputStream.write(HEARTBEAT_MSG.getBytes()); // 返回心跳包
outputStream.flush();
} else {
// 处理业务逻辑
// ...
}
lastReceiveTime = System.currentTimeMillis(); // 更新最后接收时间
}
// 判断客户端是否断开连接
if (System.currentTimeMillis() - lastReceiveTime > TIMEOUT) {
System.out.println("客户端超时未发送消息,断开连接:" + socket.getInetAddress().getHostAddress());
isRunning = false;
}
// 等待一段时间再次接收数据
Thread.sleep(1000);
}
// 关闭连接
inputStream.close();
outputStream.close();
socket.close();
clientList.remove(socket);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new Server();
}
}
```
客户端代码:
```java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
private static final String SERVER_IP = "127.0.0.1";
private static final int SERVER_PORT = 8888;
private static final int HEARTBEAT_INTERVAL = 3000; // 心跳包发送间隔
private static final int RECONNECT_INTERVAL = 5000; // 断线重连间隔
private static final String HEARTBEAT_MSG = "ping"; // 心跳包内容
private Socket socket;
private OutputStream outputStream;
private InputStream inputStream;
public Client() {
try {
// 第一次连接
connect();
// 循环发送心跳包
new Thread(() -> {
while (true) {
try {
Thread.sleep(HEARTBEAT_INTERVAL);
if (socket != null && socket.isConnected()) {
outputStream.write(HEARTBEAT_MSG.getBytes());
outputStream.flush();
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}).start();
while (true) {
// 接收数据
byte[] buffer = new byte[1024];
int len;
if ((len = inputStream.read(buffer)) != -1) {
String receiveMsg = new String(buffer, 0, len);
System.out.println("客户端接收到消息:" + receiveMsg);
}
// 等待一段时间再次接收数据
Thread.sleep(1000);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
private void connect() {
try {
socket = new Socket(SERVER_IP, SERVER_PORT);
outputStream = socket.getOutputStream();
inputStream = socket.getInputStream();
System.out.println("连接服务器成功:" + SERVER_IP + ":" + SERVER_PORT);
} catch (IOException e) {
System.out.println("连接服务器失败,5秒后重试:" + SERVER_IP + ":" + SERVER_PORT);
try {
Thread.sleep(RECONNECT_INTERVAL);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
connect(); // 断线重连
}
}
public static void main(String[] args) {
new Client();
}
}
```
这个例子实现了基本的 Socket 通信,并且加入了心跳包、客户端断线重连和服务端超时断开客户端连接的功能。其中,心跳包的发送和接收是在两个线程中分别实现的。客户端发送心跳包的间隔为 3 秒,服务端超时时间为 5 秒,客户端断线重连的间隔为 5 秒。
阅读全文