Java实现Socket长连接
Socket长连接是指在客户端和服务器之间建立一个持久的连接,可以多次传输数据而不需要每次都重新建立连接,下面我将介绍如何在Java中实现Socket长连接。

服务器端实现
import java.io.*;
import java.net.*;
public class LongConnectionServer {
public static void main(String[] args) {
int port = 8080;
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("服务器启动,监听端口: " + port);
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("客户端连接: " + clientSocket.getInetAddress().getHostAddress());
// 为每个客户端创建一个新线程处理
new Thread(() -> {
try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("收到客户端消息: " + inputLine);
// 处理客户端请求并返回响应
String response = "服务器响应: " + inputLine;
out.println(response);
}
} catch (IOException e) {
System.out.println("客户端断开连接");
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端实现
import java.io.*;
import java.net.*;
public class LongConnectionClient {
public static void main(String[] args) {
String host = "localhost";
int port = 8080;
try (Socket socket = new Socket(host, port);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader consoleIn = new BufferedReader(new InputStreamReader(System.in))) {
System.out.println("已连接到服务器: " + host + ":" + port);
// 启动一个线程来接收服务器消息
new Thread(() -> {
try {
String serverResponse;
while ((serverResponse = in.readLine()) != null) {
System.out.println("服务器响应: " + serverResponse);
}
} catch (IOException e) {
System.out.println("服务器连接已关闭");
}
}).start();
// 从控制台读取用户输入并发送到服务器
String userInput;
while ((userInput = consoleIn.readLine()) != null) {
out.println(userInput);
if ("exit".equalsIgnoreCase(userInput)) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
关键点说明
-
长连接保持:
- 服务器端使用
while(true)循环持续监听客户端连接 - 每个客户端连接在单独的线程中处理
- 客户端和服务器端都使用
while循环持续读取数据
- 服务器端使用
-
数据传输:
- 使用
BufferedReader和PrintWriter进行文本数据传输 - 对于二进制数据,可以使用
InputStream和OutputStream
- 使用
-
连接管理:
- 服务器端在客户端断开连接时捕获异常并关闭socket
- 客户端可以发送"exit"命令主动断开连接
-
线程管理:
(图片来源网络,侵删)- 服务器端为每个客户端创建新线程
- 客户端使用单独线程接收服务器消息,避免阻塞主线程
高级实现考虑
对于生产环境,你可能需要考虑:
- 连接池:管理多个客户端连接
- 心跳机制:检测连接是否存活
- 异常处理:更完善的错误处理和重连机制
- NIO实现:使用Java NIO提高性能
- SSL/TLS:加密通信内容
示例:心跳机制
// 在客户端代码中添加心跳线程
new Thread(() -> {
try {
while (!socket.isClosed()) {
out.println("heartbeat");
Thread.sleep(30000); // 30秒发送一次心跳
}
} catch (InterruptedException | IOException e) {
System.out.println("心跳线程终止");
}
}).start();
服务器端可以相应地检测心跳消息来维持连接状态。
这个实现提供了基本的Socket长连接功能,你可以根据具体需求进行扩展和优化。

