题目
如何创建一个简单的TCP客户端和服务器进行通信?
信息
- 类型:问答
- 难度:⭐
考点
TCP Socket编程, 客户端/服务器模型, 基本IO操作
快速回答
实现TCP通信需要分别创建服务器端和客户端:
- 服务器端:创建ServerSocket监听端口,通过accept()接收连接,获取输入输出流
- 客户端:创建Socket连接服务器,获取输入输出流
- 通信流程:客户端发送数据 → 服务器接收并回复 → 客户端读取回复
- 关键类:java.net.ServerSocket(服务器), java.net.Socket(客户端)
1. 原理说明
TCP是一种面向连接的可靠传输协议。Java中使用Socket和ServerSocket实现:
- ServerSocket:在服务器端监听指定端口,等待客户端连接
- Socket:客户端主动连接服务器,或服务器接受连接后创建的通信端点
- 数据流:通过Socket的InputStream和OutputStream进行双向数据传输
2. 代码示例
服务器端代码
// SimpleServer.java
import java.io.*;
import java.net.*;
public class SimpleServer {
public static void main(String[] args) throws IOException {
// 1. 创建ServerSocket监听8888端口
try (ServerSocket serverSocket = new ServerSocket(8888)) {
System.out.println("服务器启动,等待连接...");
// 2. 接受客户端连接(阻塞等待)
try (Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true)) {
System.out.println("客户端已连接");
// 3. 读取客户端消息
String clientMessage = in.readLine();
System.out.println("收到客户端消息: " + clientMessage);
// 4. 发送响应
out.println("你好客户端,已收到你的消息: " + clientMessage);
}
}
}
}客户端代码
// SimpleClient.java
import java.io.*;
import java.net.*;
public class SimpleClient {
public static void main(String[] args) throws IOException {
// 1. 连接服务器(localhost:8888)
try (Socket socket = new Socket("localhost", 8888);
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()))) {
// 2. 发送消息到服务器
out.println("Hello Server!");
// 3. 读取服务器响应
String response = in.readLine();
System.out.println("服务器响应: " + response);
}
}
}3. 最佳实践
- 资源关闭:使用try-with-resources确保Socket和流自动关闭
- 缓冲流:使用BufferedReader/PrintWriter提升IO效率
- 异常处理:实际代码需捕获IOException并处理
- 端口选择:使用1024以上的端口(0-1023为系统保留)
4. 常见错误
- 端口冲突:端口已被占用导致ServerSocket创建失败
- 连接拒绝:客户端连接地址/端口错误或服务器未启动
- 流关闭顺序:先关闭输出流可能导致输入流异常
- 阻塞问题:readLine()会阻塞直到收到换行符或流关闭
5. 扩展知识
- 多客户端处理:服务器需用多线程(每个Socket一个线程)
- UDP通信:使用DatagramSocket实现无连接通信
- NIO:Java New I/O提供非阻塞式网络编程(Selector/Channel)
- 超时设置:setSoTimeout()防止无限期阻塞