一、引言:网络编程为何如此重要?
在现代互联网应用中,几乎所有服务都离不开网络通信。Java 提供了功能强大的网络编程 API,支持 TCP、UDP 等多种协议,可广泛应用于:
-
聊天室、WebSocket
-
分布式系统通信
-
文件传输
-
HTTP 服务端/客户端通信
二、Java 网络编程基础架构图
arduino复制编辑 ┌─────────────┐
│ Client │
└────┬────────┘
│ Socket
┌────▼────┐
│ 网络 │
└────┬────┘
│ ServerSocket
┌────▼────┐
│ Server │
└─────────┘
三、Socket 与 ServerSocket 简介
类名
功能说明
Socket
客户端,用于连接服务端
ServerSocket
服务端,用于监听客户端连接请求
InetAddress
IP 地址类
四、一个最简单的 TCP 通信示例
4.1 服务端代码
java复制编辑ServerSocket serverSocket = new ServerSocket(8888);
Socket clientSocket = serverSocket.accept(); // 阻塞等待连接
InputStream in = clientSocket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String msg = reader.readLine();
System.out.println("收到客户端信息:" + msg);
4.2 客户端代码
java复制编辑Socket socket = new Socket("localhost", 8888);
OutputStream out = socket.getOutputStream();
PrintWriter writer = new PrintWriter(out, true);
writer.println("Hello Server!");
五、图示:Socket 通信流程
arduino复制编辑Client Server
↓ ↓
创建 Socket 创建 ServerSocket
↓ ↓
连接 Server(connect) 接收连接(accept)
↓ ↓
发送数据 →→→→→→→→→→→→→→→ 接收数据
←←←←←←←←←←←←←←← 发送响应
关闭连接 关闭连接
六、服务端多线程模型
单线程服务器在客户端并发量大时会被阻塞。通过为每个客户端连接分配线程,可实现多客户端并发通信。
6.1 多线程服务端结构
java复制编辑while (true) {
Socket client = serverSocket.accept();
new Thread(() -> handleClient(client)).start();
}
6.2 客户端处理方法
java复制编辑public void handleClient(Socket client) {
try (BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()))) {
String msg;
while ((msg = in.readLine()) != null) {
System.out.println("收到:" + msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
七、TCP 与 UDP 对比图
特性
TCP
UDP
是否连接
是
否
传输可靠性
高(有重传)
低(可能丢包)
传输效率
较低(握手、确认)
高(无连接、无确认)
应用示例
Web、SSH、FTP
视频会议、DNS、游戏
八、UDP 编程示例
8.1 UDP 发送端
java复制编辑DatagramSocket socket = new DatagramSocket();
byte[] data = "Hello UDP".getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("localhost"), 9999);
socket.send(packet);
8.2 UDP 接收端
java复制编辑DatagramSocket socket = new DatagramSocket(9999);
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
System.out.println("接收到 UDP 数据:" + new String(packet.getData(), 0, packet.getLength()));
九、图文:TCP 和 UDP 应用场景图解
lua复制编辑 +----------------------+ +------------------+
| TCP 应用 | | UDP 应用 |
+----------------------+ +------------------+
| HTTP / HTTPS | | 在线游戏 |
| 文件传输(FTP) | | 实时语音通话 |
| 远程登录(SSH) | | 视频会议 |
+----------------------+ +------------------+
十、粘包与拆包问题
10.1 粘包现象
多个小数据包被合并为一个发送,接收方无法区分边界。
10.2 拆包现象
一个大的数据包被拆成多段接收,数据不完整。
10.3 解决方法
-
使用分隔符(如 \n、特殊字符)
-
固定长度协议
-
在数据前加长度字段
十一、基于线程池的高并发服务器
java复制编辑ExecutorService threadPool = Executors.newCachedThreadPool();
while (true) {
Socket client = serverSocket.accept();
threadPool.execute(() -> handleClient(client));
}
优势:
-
控制线程数量,节省资源
-
提高系统吞吐量
十二、文件传输案例
12.1 客户端发送文件
java复制编辑FileInputStream fis = new FileInputStream("file.txt");
OutputStream out = socket.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
12.2 服务端保存文件
java复制编辑InputStream in = client.getInputStream();
FileOutputStream fos = new FileOutputStream("recv.txt");
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
十三、聊天室实战(简化版)
功能:
-
支持多个客户端
-
广播消息给所有人
核心:维护一个客户端集合
java复制编辑List<Socket> clientList = new CopyOnWriteArrayList<>();
当收到某个客户端消息后广播:
java复制编辑for (Socket s : clientList) {
new PrintWriter(s.getOutputStream(), true).println(msg);
}
十四、使用 NIO 实现高性能服务器(简单预览)
Java NIO 提供了非阻塞通信能力,适合百万连接场景。
java复制编辑Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(8888));
serverChannel.configureBlocking(false);
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
通过 selector 监听多个客户端 channel,实现非阻塞接入。
十五、Socket 编程常见错误与排查
问题
原因分析
Connection refused
服务端未启动或端口错误
数据接收阻塞
对方未发送或未 flush 输出流
Socket closed 异常
客户端/服务端提前关闭连接
粘包数据不完整
协议未规范,缺乏边界标识
十六、Socket + 多线程图解
arduino复制编辑Server Client
┌──────────────┐ ┌──────────────┐
│ ServerSocket │ │ Socket │
└──────┬───────┘ └──────┬───────┘
│ 接受连接 │ 连接服务器
┌──────▼───────┐ ┌───────▼────────┐
│ 多线程处理器 │ ←─────────────→│ 数据发送/接收 │
└──────────────┘ └────────────────┘
十七、Java 网络编程面试题速览
面试题
简要说明
TCP 与 UDP 区别?
TCP 可靠连接,UDP 无连接、快但不可靠
粘包/拆包的本质?
传输无边界,需要额外协议解析
多线程 Socket 通信的实现原理?
每个连接一个线程或使用线程池
Socket 与 HTTP 的关系?
HTTP 协议基于 TCP Socket 实现
Java 中如何实现心跳机制?
客户端定时发送消息,服务端监测超时
十八、总结与延伸
Java 网络编程涵盖了:
-
Socket 和 ServerSocket 的基本使用
-
TCP 和 UDP 协议通信
-
多线程并发处理客户端连接
-
实战案例(文件传输、聊天室等)
-
性能优化建议(线程池、NIO)
掌握这些内容,能让你开发出具备真实通信能力的 Java 应用程序,是进阶后端开发的重要一环。