首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 網絡編程核心技術:從 Socket 到 HTTP 協議的完整實戰指南

     編輯:Java 綜合教學

前言:網絡編程是分布式系統的基石

Java `java.net` 包提供了從底層 Socket 到高層 HTTP/URL 的完整網絡 API。本文系統講解:InetAddress 域名解析、TCP/UDP Socket 通信模型、ServerSocket 服務端編程、URL/URLConnection 資源訪問、數據報編程、協議層次模型,並附帶可運行的客戶端/服務端完整代碼示例。

一、網絡基礎概念速覽

概念說明
IP 地址32 位 (IPv4) / 128 位 (IPv6) 唯一標識,含網絡 ID + 主機 ID
域名系統 (DNS)將域名映射為 IP,分佈式層次命名庫
端口16 位整數 (0-65535),標識進程通信端點。知名端口:HTTP 80, HTTPS 443, FTP 21, SSH 22, SMTP 25
協議通信雙方遵守的規則。TCP:可靠、面向連接、字節流;UDP:不可靠、無連接、數據報
C/S 模型客戶端發起請求,服務端監聽端口並響應,支持併發多客戶端

二、InetAddress:IP 與域名的雙向解析

2.1 三大工廠方法

// 本機地址
InetAddress local = InetAddress.getLocalHost(); // PCOS-10271310/192.168.1.102

// 域名 → IP (DNS 查詢)
InetAddress netEase = InetAddress.getByName("www.163.com"); // www.163.com/222.186.132.123

// IP 字符串 → InetAddress
InetAddress byIp = InetAddress.getByName("192.168.0.22"); // /192.168.0.22

// 批量解析 (負載均衡、CDN 多 IP)
InetAddress[] baidu = InetAddress.getAllByName("www.baidu.com");
// 14.215.177.38, 14.215.177.37 ...

2.2 常用實例方法

  • `getHostAddress()` — IP 字符串
  • `getHostName()` — 域名/主機名
  • `getAddress()` — 原始字節數組 (網絡序)
  • `isMulticastAddress()` — 判斷組播地址 (224.0.0.0 - 239.255.255.255)

三、TCP Socket 編程:可靠字節流通信

3.1 服務端標準流程

public class TcpServer {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8888); // 綁定端口,進入監聽
        System.out.println("Server started on 8888");
        while (true) {
            Socket client = server.accept(); // 阻塞等待連接
            // 每客戶端一線程處理 (生產用線程池)
            new Thread(() -> handle(client)).start();
        }
    }
    static void handle(Socket socket) {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
             PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
            String msg;
            while ((msg = in.readLine()) != null) {
                System.out.println("Received: " + msg);
                out.println("Echo: " + msg); // 應用層協議:換行結尾
            }
        } catch (IOException e) { e.printStackTrace(); }
    }
}

3.2 客戶端標準流程

public class TcpClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 8888);
        try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
             PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
             BufferedReader console = new BufferedReader(new InputStreamReader(System.in))) {
            String line;
            while ((line = console.readLine()) != null) {
                out.println(line); // 發送
                System.out.println("Server: " + in.readLine()); // 接收回顯
            }
        }
    }
}

3.3 關鍵點總結

  • Socket 獲取 `InputStream`/`OutputStream` 進行讀寫。
  • 字節流 → `InputStreamReader`/`OutputStreamWriter` → `BufferedReader`/`PrintWriter` 提高效率與便利性。
  • 應用層協議設計:定界符(換行)、長度前綴、序列化(Protobuf/JSON)。
  • 服務端必須多線程/IO 多路復用 (NIO/Netty) 支持併發。

四、UDP 數據報編程:輕量無連接通信

4.1 核心類

  • `DatagramSocket` — 發送/接收端點,綁定端口。
  • `DatagramPacket` — 數據容器,含字節數組、長度、目標 IP/端口。

4.2 服務端接收

DatagramSocket socket = new DatagramSocket(9999);
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
while (true) {
    socket.receive(packet); // 阻塞接收
    String msg = new String(packet.getData(), 0, packet.getLength());
    System.out.println(packet.getAddress() + ":" + packet.getPort() + " -> " + msg);
    // 回複
    byte[] resp = ("ACK: " + msg).getBytes();
    DatagramPacket reply = new DatagramPacket(resp, resp.length, packet.getAddress(), packet.getPort());
    socket.send(reply);
}

4.3 客戶端發送

DatagramSocket socket = new DatagramSocket();
InetAddress server = InetAddress.getByName("localhost");
String msg = "Hello UDP";
DatagramPacket packet = new DatagramPacket(msg.getBytes(), msg.length(), server, 9999);
socket.send(packet);
// 接收回複
byte[] buf = new byte[1024];
DatagramPacket resp = new DatagramPacket(buf, buf.length);
socket.receive(resp);
System.out.println(new String(resp.getData(), 0, resp.getLength()));
socket.close();

五、URL 與 URLConnection:高層資源訪問抽象

5.1 URL 組件解析

protocol://host:port/path?query#fragment
  http   www.ex.com 80  /api/user?id=1  #section
  • `getProtocol()` / `getHost()` / `getPort()` / `getPath()` / `getQuery()` / `getRef()`
  • 構造器:`new URL("https://host:80/path")`、`new URL(baseUrl, relativePath)`

5.2 下載資源 (圖片/網頁/文件)

// 方式 1:URL.openStream() 獲取輸入流
URL url = new URL("https://example.com/image.png");
try (InputStream in = url.openStream();
     FileOutputStream out = new FileOutputStream("image.png")) {
    byte[] buf = new byte[4096];
    int len;
    while ((len = in.read(buf)) != -1) out.write(buf, 0, len);
}

// 方式 2:URLConnection 獲取更多控制 (Header、重定向、超時)
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(10000);
conn.setRequestProperty("User-Agent", "Java/17");
if (conn.getResponseCode() == 200) {
    try (InputStream in = conn.getInputStream()) { /* 讀取 */ }
    // 獲取元數據
    String contentType = conn.getContentType(); // image/png
    long length = conn.getContentLengthLong();
    long modified = conn.getLastModified();
}

5.3 URLEncoder 表單編碼

String encoded = URLEncoder.encode("參數值 with spaces", StandardCharsets.UTF_8);
// 參數值+with+spaces (空格→+,特殊字符→%XX)

六、OSI 七層模型與 TCP/IP 四層對照

OSI 七層TCP/IP 四層功能典型協議/設備
7. 應用層應用層用戶接口HTTP, FTP, SMTP, DNS
6. 表示層數據格式轉換SSL/TLS, JSON, Protobuf
5. 會話層會話管理RPC, WebSocket
4. 傳輸層傳輸層端到端可靠/不可靠傳輸TCP, UDP
3. 網絡層網際層路由、邏輯寻址IP, ICMP, 路由器
2. 數據鏈路層網絡接口層幀封裝、MAC 寻址以太網, WiFi, 交換機
1. 物理層比特傳輸光纖, 雙絞線, 集線器

Socket 工作在傳輸層 (TCP/UDP) 之上,為應用層提供通信端點抽象。

七、實戰建議與避坑指南

  1. TCP 粘包/拆包:流式協議無消息邊界,必須自定義應用層協議 (長度頭、分隔符、定長)。
  2. 超時設置:`socket.setSoTimeout(ms)` 防止讀寫無限阻塞;連接超時 `new Socket()` 無參構造後 `connect(addr, timeout)`。
  3. 資源關閉順序:先關流,後關 Socket;`try-with-resources` 自動處理。
  4. 字符集統一:`StandardCharsets.UTF_8` 避免中文亂碼。
  5. UDP 丟包/亂序/重複:應用層需實現 ACK/重傳/排序 (如 QUIC/RUDP) 或接受不可靠 (視頻流、日志)。
  6. 高併發服務端:生產環境請使用 Netty (NIO)、Tomcat/Jetty (Servlet)、Spring Boot (嵌入式容器),勿手寫線程池 ServerSocket。
  7. HTTPS/SSL:`HttpsURLConnection` 自動處理證書驗證;自簽證書需自定義 `TrustManager`/`HostnameVerifier`。

總結

Java 網絡編程從 `InetAddress` 解析開始,核心分兩條線:TCP Socket (可靠流) 與 UDP Datagram (輕量報文),上層封裝 `URL/URLConnection` 簡化 HTTP 資源訪問。掌握協議分層、IO 流轉換、應用層協議設計、併發模型選擇,並善用成熟框架 (Netty, OkHttp, Spring WebClient),即可構建高性能、穩健的網絡應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved