深入理解 Java 网络编程:基于《Head First Java》第 15 章解析
网络通信 是现代应用程序不可或缺的一部分,而 Java 作为一门强大的面向对象编程语言,提供了完整的 网络 API,让开发者可以轻松编写 基于 TCP/IP 协议的网络应用。
本文基于《Head First Java》第 15 章 “网络与线程——网络联机”,带你深入理解 Java 网络通信,并通过代码示例,帮助你掌握 Socket、服务器/客户端模型 以及 多线程处理并发请求。
📌 1. Java 网络通信基础
Java 提供了 java.net
包来支持 TCP/IP 和 UDP 这两种主流协议。
- TCP(传输控制协议):面向连接,保证数据有序、完整传输,如 HTTP、FTP。
- UDP(用户数据报协议):无连接,发送数据不保证到达顺序,如视频直播、在线游戏。
在 Java 中,最常用的类包括:
Socket
:用于创建客户端连接。ServerSocket
:用于创建服务器监听。InetAddress
:用于表示 IP 地址信息。
📌 2. 使用 Socket
进行网络通信(TCP)
Socket
是 Java 处理 TCP 连接 的核心类,它提供了一种 客户端-服务器 模型,让两个应用程序能够在网络中进行数据交换。
(1)构建服务器
服务器端主要使用 ServerSocket
监听客户端请求,并通过 accept()
方法接受连接:
import java.io.*;
import java.net.*;
public class SimpleServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(5000)) {
System.out.println("服务器已启动,等待客户端连接...");
while (true) {
Socket socket = serverSocket.accept(); // 等待客户端连接
System.out.println("客户端已连接:" + socket.getInetAddress());
// 读取客户端消息
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter output = new PrintWriter(socket.getOutputStream(), true);
String receivedMessage = input.readLine();
System.out.println("收到客户端消息:" + receivedMessage);
// 发送响应
output.println("服务器收到:" + receivedMessage);
// 关闭连接
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
(2)构建客户端
客户端使用 Socket
连接到服务器,并发送数据:
import java.io.*;
import java.net.*;
public class SimpleClient {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 5000)) {
PrintWriter output = new PrintWriter(socket.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 发送消息
output.println("Hello, Server!");
// 读取服务器响应
String response = input.readLine();
System.out.println("服务器回应:" + response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
(3)运行结果
先运行 SimpleServer
,然后运行 SimpleClient
,可以看到:
服务器已启动,等待客户端连接...
客户端已连接:/127.0.0.1
收到客户端消息:Hello, Server!
客户端输出:
服务器回应:服务器收到:Hello, Server!
📌 总结:
- 服务器创建
ServerSocket
并等待客户端连接。 - 客户端通过
Socket
连接服务器并发送消息。 - 服务器通过
accept()
方法接受连接,读取数据并返回响应。
📌 3. 使用多线程处理多个客户端
在实际开发中,服务器需要同时处理多个客户端请求,ServerSocket
默认是 阻塞模式,意味着 每次只能处理一个客户端。
为了解决这个问题,我们可以使用 多线程 让每个客户端连接都由一个独立线程处理。
(1)修改服务器支持多线程
import java.io.*;
import java.net.*;
public class MultiThreadServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(5000)) {
System.out.println("服务器已启动,等待客户端连接...");
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("新客户端连接:" + clientSocket.getInetAddress());
// 为每个客户端启动新线程
new ClientHandler(clientSocket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 处理客户端请求的线程
class ClientHandler extends Thread {
private Socket clientSocket;
public ClientHandler(Socket socket) {
this.clientSocket = socket;
}
public void run() {
try (
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter output = new PrintWriter(clientSocket.getOutputStream(), true)
) {
String message = input.readLine();
System.out.println("收到客户端消息:" + message);
output.println("服务器收到:" + message);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
📌 优化点:
- 每个客户端连接都由一个
ClientHandler
线程处理,防止服务器阻塞。 while (true)
监听多个客户端,保证服务器持续运行。
📌 4. UDP 编程(无连接通信)
UDP 适用于 低延迟场景,如游戏、视频等。Java 提供了 DatagramSocket
和 DatagramPacket
处理 UDP 数据。
(1)UDP 服务器
import java.net.*;
public class UDPServer {
public static void main(String[] args) {
try (DatagramSocket socket = new DatagramSocket(5000)) {
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
System.out.println("UDP 服务器启动,等待数据...");
socket.receive(packet);
String message = new String(packet.getData(), 0, packet.getLength());
System.out.println("收到客户端消息:" + message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
(2)UDP 客户端
import java.net.*;
public class UDPClient {
public static void main(String[] args) {
try (DatagramSocket socket = new DatagramSocket()) {
byte[] buffer = "Hello UDP Server!".getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("localhost"), 5000);
socket.send(packet);
System.out.println("消息已发送");
} catch (Exception e) {
e.printStackTrace();
}
}
}
📌 5. 结语
在本章内容中,我们学习了:
✅ Java 网络编程基础(TCP / UDP)
✅ 使用 Socket
进行 TCP 通信
✅ 多线程服务器处理多个客户端
✅ UDP 服务器与客户端通信
通过这些示例,你可以构建自己的网络聊天程序、远程调用服务、多人在线游戏等应用!🚀