java的 Socket通信完整实例(心跳包,客户端断线重连,服务端超时断开客户端连接)要有客户端服务端切要解析他们聊天数据
时间: 2023-11-06 13:04:06 浏览: 54
以下是Java Socket通信的完整实例,包括心跳包、客户端断线重连、服务端超时断开客户端连接以及聊天数据的解析。
客户端代码:
```java
import java.io.*;
import java.net.*;
public class Client {
private static final int HEARTBEAT_INTERVAL = 5000; // 心跳包发送间隔时间
private static final int RECONNECT_INTERVAL = 5000; // 断线重连间隔时间
private String serverHost = "127.0.0.1"; // 服务器地址
private int serverPort = 8888; // 服务器端口号
private Socket socket;
private BufferedReader reader;
private BufferedWriter writer;
private boolean connected = false; // 是否已连接
public void connect() {
try {
socket = new Socket(serverHost, serverPort);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
connected = true;
System.out.println("连接服务器成功!");
} catch (IOException e) {
System.out.println("连接服务器失败!");
try {
Thread.sleep(RECONNECT_INTERVAL);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
connect(); // 断线重连
}
}
public void send(String message) {
try {
writer.write(message);
writer.newLine();
writer.flush();
} catch (IOException e) {
System.out.println("发送消息失败!");
connected = false;
try {
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public void startHeartbeat() {
new Thread(() -> {
while (connected) {
send("heartbeat"); // 发送心跳包
try {
Thread.sleep(HEARTBEAT_INTERVAL);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
public void receive() {
new Thread(() -> {
while (connected) {
try {
String message = reader.readLine();
if (message == null) {
System.out.println("与服务器断开连接!");
connected = false;
try {
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
connect(); // 断线重连
} else if (message.equals("heartbeat")) {
// 收到心跳包,不做处理
} else {
System.out.println("收到消息:" + message);
// 解析聊天数据
// ...
}
} catch (IOException e) {
System.out.println("接收消息失败!");
connected = false;
try {
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
connect(); // 断线重连
}
}
}).start();
}
public void start() {
connect();
startHeartbeat();
receive();
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}
}
```
服务端代码:
```java
import java.io.*;
import java.net.*;
import java.util.*;
public class Server {
private static final int CLIENT_TIMEOUT = 10000; // 客户端超时时间
private int port = 8888; // 服务器端口号
private ServerSocket server;
private List<ClientHandler> clients = new ArrayList<>();
public void start() {
try {
server = new ServerSocket(port);
System.out.println("服务器启动,监听端口:" + port);
while (true) {
Socket socket = server.accept();
System.out.println("客户端连接:" + socket.getRemoteSocketAddress());
ClientHandler handler = new ClientHandler(socket);
clients.add(handler);
handler.start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (server != null) {
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void remove(ClientHandler handler) {
clients.remove(handler);
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
class ClientHandler extends Thread {
private Socket socket;
private BufferedReader reader;
private BufferedWriter writer;
private boolean connected = false; // 是否已连接
public ClientHandler(Socket socket) {
this.socket = socket;
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
connected = true;
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String message) {
try {
writer.write(message);
writer.newLine();
writer.flush();
} catch (IOException e) {
System.out.println("发送消息失败!");
connected = false;
try {
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public void run() {
try {
socket.setSoTimeout(CLIENT_TIMEOUT); // 设置超时时间
while (connected) {
String message = reader.readLine();
if (message == null) {
System.out.println("客户端断开连接:" + socket.getRemoteSocketAddress());
connected = false;
try {
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
remove(this);
} else if (message.equals("heartbeat")) {
// 收到心跳包,不做处理
} else {
System.out.println("收到消息:" + message);
// 解析聊天数据
// ...
for (ClientHandler handler : clients) {
if (handler != this) {
handler.send(message);
}
}
}
}
} catch (SocketTimeoutException e) {
System.out.println("客户端超时断开连接:" + socket.getRemoteSocketAddress());
connected = false;
try {
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
remove(this);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
```
在以上代码中,我们使用了心跳包机制来检测客户端和服务器端的连接状态,并使用断线重连机制来处理客户端的连接异常。同时,我们还设置了客户端超时时间和服务端超时断开客户端连接的机制,来保证连接的稳定性和安全性。
在收到聊天数据后,我们可以根据约定好的数据包格式进行解析,并对解析出的数据进行处理。在以上代码中,我们只是简单地打印了收到的消息,并将其转发给了其他客户端。具体的聊天数据解析和处理方式可以根据实际需求进行设计。