Java 服务器与客户端通信实现指南
在 Java 网络编程中,实现服务器与客户端的对话主要依赖于 Socket(套接字) 编程模型,通过 Socket,我们可以实现基于 TCP 协议的双向数据传输。
核心类介绍
java.net.ServerSocket:用于服务器端,负责在指定端口监听客户端的连接请求。java.net.Socket:用于客户端和服务器端,负责建立连接并进行数据的输入与输出。java.io.InputStream/java.io.OutputStream:用于处理数据流,实现数据的读取和发送。
实现流程
服务器端流程
- 创建
ServerSocket对象并绑定端口。 - 调用
accept()方法进入阻塞状态,等待客户端连接。 - 连接建立后,通过 Socket 获取
InputStream(读取客户端数据)和OutputStream(发送数据给客户端)。 - 进行数据交互。
- 关闭资源。
客户端流程
- 创建
Socket对象,指定服务器的 IP 地址和端口号。 -
连接成功后,通过 Socket 获取
InputStream和OutputStream。 - 进行数据交互。
- 关闭资源。
代码示例
下面是一个简单的“回声(Echo)”对话示例,服务器接收客户端的消息并原样返回。
服务器端代码 (SimpleServer.java)
import java.io.;
import java.net.;
public class SimpleServer {
public static void main(String[] args) {
int port = 8888;
// 使用 try-with-resources 自动关闭资源
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("服务器已启动,正在等待客户端连接...");
// 阻塞等待客户端连接
Socket socket = serverSocket.accept();
System.out.println("客户端已连接: " + socket.getInetAddress());
// 设置输入流(读取)和输出流(发送)
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("收到客户端消息: " + inputLin
e);
// 将消息原样返回给客户端
out.println("服务器回复: " + inputLine);
if ("exit".equalsIgnoreCase(inputLine)) {
break;
}
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码 (SimpleClient.java)
import java.io.;
import java.net.;
import java.util.Scanner;
public class SimpleClient {
public static void main(String[] args) {
String hostname = "localhost";
int port = 8888;
try (Socket socket = new Socket(hostname, port)) {
// 设置输出流(发送)和输入流(读取)
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Scanner scanner = new Scanner(System.in);
String userInput;
System.out.println("已连接到服务器,输入 'exit' 退出。");
while (true) {
System.out.print("请输入消息: ");
userInput = scanner.nextLine();
// 发送数据到服务器
out.println(user
Input);
// 接收服务器的回复
String response = in.readLine();
System.out.println(response);
if ("exit".equalsIgnoreCase(userInput)) {
break;
}
}
} catch (UnknownHostException e) {
System.err.println("无法找到主机: " + e.getMessage());
} catch (IOException e) {
System.err.println("I/O 错误: " + e.getMessage());
}
}
}
- 阻塞机制:
accept()和readLine()都是阻塞式方法,这意味着程序会停在那里,直到有新的连接或新数据到达。 - 资源管理:务必使用 try-with-resources 语句或在
finally块中关闭 Socket 和流,以防止内存泄漏和端口占用。 - 多客户端支持:上述示例仅支持单个客户端,若要实现多用户同时在线,服务器端必须为每个
accept()返回的 Socket 创建一个新的 线程 (Thread) 来处理对话。 - 异常处理:网络通信极易受到网络波动影响,必须妥善处理
IOException以保证程序的稳定性。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/488550.html



