Java网络编程核心实战详解
你提供的代码清单展示了 Java 网络编程的核心类和方法。以下是这些方法的分类、对比和关键代码示例。
一、核心操作分类与对比
| 操作类型 | 核心类/接口 | 关键方法/特性 | 适用场景 |
|---|---|---|---|
| IP地址与主机名解析 | InetAddress | getLocalHost(),getByName(),getAllByName() | 获取本地或远程主机的IP地址信息 |
| TCP Socket通信 | Socket,ServerSocket | Socket(String host, int port),getInputStream(),getOutputStream() | 面向连接的、可靠的、基于流的网络通信(如HTTP、FTP) |
| URL 解析与访问 | URL,URLConnection,HttpURLConnection | URL(String spec),openConnection(),getHeaderFields() | 解析URL结构,建立HTTP/HTTPS连接并获取资源 |
| UDP 数据报通信 | DatagramSocket,DatagramPacket | DatagramSocket(int port),send(DatagramPacket p),receive(DatagramPacket p) | 无连接的、不可靠的、基于数据包的网络通信(如DNS、音视频流) |
二、关键代码示例
1. 使用 InetAddress 获取网络地址信息
InetAddress类用于表示IP地址(IPv4或IPv6),并提供了获取主机名和IP地址的方法。
// 对应 listing 1 import java.net.InetAddress; import java.net.UnknownHostException; public class InetAddressExample { public static void main(String[] args) throws UnknownHostException { // 获取本机地址 InetAddress localAddress = InetAddress.getLocalHost(); System.out.println("Local Host: " + localAddress); // 通过主机名获取单个IP地址 InetAddress remoteAddress = InetAddress.getByName("www.example.com"); System.out.println("Single Address for www.example.com: " + remoteAddress); // 通过主机名获取所有IP地址(适用于有多个IP的主机,如负载均衡) InetAddress[] allAddresses = InetAddress.getAllByName("www.google.com"); System.out.println("All Addresses for www.google.com:"); for (InetAddress addr : allAddresses) { System.out.println(" " + addr); } } }2. 使用 Socket 进行 TCP 客户端通信
Socket类用于建立到服务器的TCP连接,并通过流进行数据读写。
// 对应 listing 2 (TCP客户端示例) import java.io.*; import java.net.*; public class TcpClientExample { public static void main(String[] args) throws Exception { String host = "whois.internic.net"; int port = 43; // Whois服务标准端口 String query = (args.length == 0) ? "example.com" : args[0]; // 1. 创建Socket连接到服务器 try (Socket socket = new Socket(host, port)) { // 2. 获取输入输出流 InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); // 3. 发送请求数据 String request = query + " "; out.write(request.getBytes()); out.flush(); // 确保数据发送 // 4. 读取服务器响应 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } // try-with-resources 自动关闭Socket } }3. 使用 URL 和 URLConnection 访问网络资源
URL类用于解析URL,URLConnection用于建立连接并获取元数据和内容。
// 综合 listing 3, 4, 5 的要点 import java.net.*; import java.io.*; import java.util.Date; import java.util.Map; import java.util.List; public class UrlConnectionExample { public static void main(String[] args) throws Exception { URL url = new URL("https://httpbin.org/get"); // 打开连接 (通用URLConnection) URLConnection connection = url.openConnection(); // 如果是HTTP/HTTPS,可以转换为HttpURLConnection以使用HTTP特有方法 if (connection instanceof HttpURLConnection) { HttpURLConnection httpConn = (HttpURLConnection) connection; httpConn.setRequestMethod("GET"); httpConn.setConnectTimeout(5000); // 设置连接超时 httpConn.setReadTimeout(5000); // 设置读取超时 // 获取HTTP响应信息 System.out.println("Response Code: " + httpConn.getResponseCode()); System.out.println("Response Message: " + httpConn.getResponseMessage()); // 获取所有响应头 Map<String, List<String>> headers = httpConn.getHeaderFields(); for (Map.Entry<String, List<String>> entry : headers.entrySet()) { System.out.println(entry.getKey() + ": " + entry.getValue()); } } // 获取连接通用信息 (listing 4) System.out.println("Content-Type: " + connection.getContentType()); System.out.println("Content-Length: " + connection.getContentLengthLong()); long lastModified = connection.getLastModified(); if (lastModified != 0) { System.out.println("Last-Modified: " + new Date(lastModified)); } // 读取响应内容 try (BufferedReader reader = new BufferedReader( new InputStreamReader(connection.getInputStream()))) { String line; System.out.println(" === Response Body ==="); while ((line = reader.readLine()) != null) { System.out.println(line); } } } }4. 使用 DatagramSocket 进行 UDP 通信
DatagramSocket和DatagramPacket用于无连接的UDP通信,数据以数据包形式发送和接收。
// 对应 listing 6 (UDP 客户端/服务器示例) import java.net.*; public class UdpExample { // 服务器端方法 public static void startServer(int port) throws Exception { try (DatagramSocket socket = new DatagramSocket(port)) { System.out.println("UDP Server started on port " + port); byte[] buffer = new byte[1024]; while (true) { // 1. 创建数据包用于接收数据 DatagramPacket packet = new DatagramPacket(buffer, buffer.length); // 2. 接收数据包 (阻塞方法) socket.receive(packet); // 3. 处理接收到的数据 String received = new String(packet.getData(), 0, packet.getLength()); InetAddress clientAddress = packet.getAddress(); int clientPort = packet.getPort(); System.out.printf("Received from %s:%d -> %s%n", clientAddress.getHostAddress(), clientPort, received); // 4. 准备响应数据 String response = "Echo: " + received; byte[] responseData = response.getBytes(); DatagramPacket responsePacket = new DatagramPacket( responseData, responseData.length, clientAddress, clientPort); // 5. 发送响应 socket.send(responsePacket); } } } // 客户端方法 public static void startClient(String serverHost, int serverPort) throws Exception { try (DatagramSocket socket = new DatagramSocket()) { InetAddress serverAddress = InetAddress.getByName(serverHost); String message = "Hello UDP Server!"; byte[] sendData = message.getBytes(); // 1. 创建并发送数据包 DatagramPacket sendPacket = new DatagramPacket( sendData, sendData.length, serverAddress, serverPort); socket.send(sendPacket); System.out.println("Sent: " + message); // 2. 准备接收响应 byte[] receiveData = new byte[1024]; DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); socket.receive(receivePacket); // 设置超时: socket.setSoTimeout(5000); // 3. 处理响应 String response = new String(receivePacket.getData(), 0, receivePacket.getLength()); System.out.println("Received: " + response); } } public static void main(String[] args) throws Exception { if (args.length > 0 && args[0].equals("server")) { startServer(9876); } else { startClient("localhost", 9876); } } }三、核心要点总结
- InetAddress:用于IP地址和主机名的相互解析,不涉及网络连接本身。
- TCP vs UDP:
- TCP (
Socket/ServerSocket):面向连接、可靠、基于字节流。适用于需要可靠数据传输的场景,如网页浏览(HTTP)、文件传输(FTP)、电子邮件(SMTP)。 - UDP (
DatagramSocket/DatagramPacket):无连接、不可靠、基于数据报。适用于对实时性要求高、能容忍少量丢包的场景,如视频流、DNS查询、在线游戏。
- TCP (
- URL 处理:
URL类ruchtig解析URL字符串,URLConnection提供了建立连接、读取响应头和内容的通用方法。对于HTTP/HTTPS,使用其子类HttpURLConnection可以访问HTTP特有的功能,如请求方法、响应码等。 - 资源管理:网络连接(
Socket、URLConnection)、流(InputStream、OutputStream)都是需要关闭的系统资源。务必使用try-with-resources语句或在finally块中确保它们被关闭,以避免资源泄漏。 - 异常处理:网络操作可能抛出多种受检异常,如
UnknownHostException、SocketException、IOException、MalformedURLException等,必须进行妥善处理。
参考来源
- Java网络编程(Socket、URLConnection)
- java 网络编程基础_Java网络编程基础(一)
- java.net 包详解
- Java之网络编程
- Java基础——网络编程(Socket编程)
