三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Java网络编程核心实战详解

Java网络编程核心实战详解

你提供的代码清单展示了 Java 网络编程的核心类和方法。以下是这些方法的分类、对比和关键代码示例。

一、核心操作分类与对比

操作类型核心类/接口关键方法/特性适用场景
IP地址与主机名解析InetAddressgetLocalHost(),getByName(),getAllByName()获取本地或远程主机的IP地址信息
TCP Socket通信Socket,ServerSocketSocket(String host, int port),getInputStream(),getOutputStream()面向连接的、可靠的、基于流的网络通信(如HTTP、FTP)
URL 解析与访问URL,URLConnection,HttpURLConnectionURL(String spec),openConnection(),getHeaderFields()解析URL结构,建立HTTP/HTTPS连接并获取资源
UDP 数据报通信DatagramSocket,DatagramPacketDatagramSocket(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 通信

DatagramSocketDatagramPacket用于无连接的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); } } }

三、核心要点总结

  1. InetAddress:用于IP地址和主机名的相互解析,不涉及网络连接本身。
  2. TCP vs UDP
    • TCP (Socket/ServerSocket):面向连接、可靠、基于字节流。适用于需要可靠数据传输的场景,如网页浏览(HTTP)、文件传输(FTP)、电子邮件(SMTP)。
    • UDP (DatagramSocket/DatagramPacket):无连接、不可靠、基于数据报。适用于对实时性要求高、能容忍少量丢包的场景,如视频流、DNS查询、在线游戏。
  3. URL 处理URL类ruchtig解析URL字符串,URLConnection提供了建立连接、读取响应头和内容的通用方法。对于HTTP/HTTPS,使用其子类HttpURLConnection可以访问HTTP特有的功能,如请求方法、响应码等。
  4. 资源管理:网络连接(SocketURLConnection)、流(InputStreamOutputStream)都是需要关闭的系统资源。务必使用try-with-resources语句或在finally块中确保它们被关闭,以避免资源泄漏。
  5. 异常处理:网络操作可能抛出多种受检异常,如UnknownHostExceptionSocketExceptionIOExceptionMalformedURLException等,必须进行妥善处理。

参考来源

  • Java网络编程(Socket、URLConnection)
  • java 网络编程基础_Java网络编程基础(一)
  • java.net 包详解
  • Java之网络编程
  • Java基础——网络编程(Socket编程)
← 返回列表