网络编程¶
📖 章节简介¶
本章将介绍Java的网络编程,包括Socket编程、HTTP客户端和服务器的基本使用。
上图覆盖 TCP、UDP 与 HTTP 三类常见网络编程模式及定位。
🌐 Socket编程¶
1. Socket基础¶
Java
// Socket客户端
import java.io.*;
import java.net.*;
public class SocketClient {
public static void main(String[] args) {
String host = "localhost";
int port = 8080;
try (Socket socket = new Socket(host, port);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
// 发送消息
out.println("Hello, Server!");
// 接收响应
String response = in.readLine();
System.out.println("服务器响应: " + response);
} catch (IOException e) {
System.out.println("连接失败: " + e.getMessage());
}
}
}
// Socket服务器
import java.io.*;
import java.net.*;
public class SocketServer {
public static void main(String[] args) {
int port = 8080;
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("服务器启动,监听端口: " + port);
while (true) {
try (Socket clientSocket = serverSocket.accept();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {
System.out.println("客户端连接: " + clientSocket.getInetAddress());
// 接收消息
String message = in.readLine();
System.out.println("客户端消息: " + message);
// 发送响应
out.println("Hello, Client!");
} catch (IOException e) {
System.out.println("处理客户端失败: " + e.getMessage());
}
}
} catch (IOException e) {
System.out.println("服务器启动失败: " + e.getMessage());
}
}
}
2. UDP编程¶
Java
// UDP发送端
import java.net.*;
public class UDPSender {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket();
String message = "Hello, UDP!";
byte[] buffer = message.getBytes();
InetAddress address = InetAddress.getByName("localhost");
int port = 9876;
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port);
socket.send(packet);
System.out.println("消息已发送");
socket.close();
}
}
// UDP接收端
import java.net.*;
public class UDPReceiver {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9876);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
System.out.println("等待接收消息...");
socket.receive(packet);
String message = new String(packet.getData(), 0, packet.getLength());
System.out.println("收到消息: " + message);
System.out.println("发送者: " + packet.getAddress());
socket.close();
}
}
🌍 HTTP客户端¶
1. HttpURLConnection¶
Java
// HTTP客户端
import java.io.*;
import java.net.*;
public class HttpClient {
public static void main(String[] args) throws Exception {
String urlString = "https://api.example.com/data";
// 注意:new URL(String) 自 Java 20 起已弃用,使用 URI.create().toURL()
URL url = URI.create(urlString).toURL();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求方法
connection.setRequestMethod("GET");
// 设置请求头
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("User-Agent", "MyClient/1.0");
// 设置超时
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
int responseCode = connection.getResponseCode();
System.out.println("响应码: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) {
// 读取响应
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String line;
StringBuilder response = new StringBuilder();
while ((line = in.readLine()) != null) {
response.append(line);
}
in.close();
System.out.println("响应内容: " + response.toString());
} else {
System.out.println("请求失败");
}
connection.disconnect();
}
}
2. POST请求¶
Java
// POST请求
import java.io.*;
import java.net.*;
public class HttpPostClient {
public static void main(String[] args) throws Exception {
String urlString = "https://api.example.com/users";
URL url = URI.create(urlString).toURL();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求方法
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
// 启用输出
connection.setDoOutput(true);
// 发送请求体
String jsonInputString = "{\"name\":\"张三\",\"age\":25}";
try (OutputStream os = connection.getOutputStream()) {
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}
int responseCode = connection.getResponseCode();
System.out.println("响应码: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED) {
// 读取响应
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String line;
StringBuilder response = new StringBuilder();
while ((line = in.readLine()) != null) {
response.append(line);
}
in.close();
System.out.println("响应内容: " + response.toString());
}
connection.disconnect();
}
}
💡 最佳实践¶
1. 异常处理¶
Java
// 网络编程异常处理
public class NetworkExceptionHandling {
// ✅ 好的做法:处理所有可能的异常
public void connectToServer(String host, int port) {
try {
Socket socket = new Socket(host, port);
// 处理连接
} catch (UnknownHostException e) {
System.out.println("未知主机: " + e.getMessage());
} catch (ConnectException e) {
System.out.println("连接被拒绝: " + e.getMessage());
} catch (SocketTimeoutException e) {
System.out.println("连接超时: " + e.getMessage());
} catch (IOException e) {
System.out.println("IO异常: " + e.getMessage());
}
}
// ❌ 不好的做法:只捕获IOException
public void connectToServerUnsafe(String host, int port) {
try {
Socket socket = new Socket(host, port);
// 处理连接
} catch (IOException e) {
System.out.println("连接失败"); // 信息不明确
}
}
}
2. 资源管理¶
Java
import java.io.*;
import java.net.*;
// 网络资源管理
public class NetworkResourceManagement {
// ✅ 好的做法:使用try-with-resources
// 注意:new URL(String) 自 Java 20 起已弃用,推荐使用 URI.create(url).toURL()
public void sendRequest1(String url) {
try (BufferedReader in = new BufferedReader(
new InputStreamReader(URI.create(url).toURL().openStream()))) {
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("请求失败");
}
}
// ❌ 不好的做法:手动关闭资源
public void sendRequest2(String url) {
BufferedReader in = null;
try {
in = new BufferedReader(
new InputStreamReader(URI.create(url).toURL().openStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("请求失败");
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
System.out.println("关闭失败");
}
}
}
}
}
📝 练习题¶
基础题¶
- 什么是Socket?
- TCP和UDP有什么区别?
- 如何发送HTTP请求?
进阶题¶
- 实现一个简单的聊天程序。
- 创建一个HTTP服务器。
- 使用线程处理多个客户端。
实践题¶
- 创建一个文件传输工具。
- 实现一个简单的Web爬虫。
- 构建一个在线投票系统。
📚 推荐阅读¶
🔗 下一章¶
实战项目 - 通过一个完整的学生管理系统项目综合运用所学知识。