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

Java Socket 網路程式設計完全指南:從基礎到多線程實戰

     編輯:Java 相關知識

網路程式設計核心模型

網路程式設計本質是兩個行程間的資料交換。Client/Server 模型中,Server 提供固定位址(IP + Port)監聽,Client 主動發起連線。Java java.net 套件封裝底層 Socket 細節,提供 ServerSocket、Socket、InetAddress 等核心類別,搭配 java.io 串流完成資料收發。

基礎版:單線程回聲伺服器

// Server
ServerSocket server = new ServerSocket(5678);
Socket client = server.accept(); // 阻塞等待

BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true); // auto-flush

String line;
while ((line = in.readLine()) != null) {
    System.out.println("Received: " + line);
    out.println("Echo: " + line);
    if ("end".equalsIgnoreCase(line)) break;
}
client.close();
// Client
Socket server = new Socket(InetAddress.getLocalHost(), 5678);
BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintWriter out = new PrintWriter(server.getOutputStream(), true);
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));

String input;
while ((input = keyboard.readLine()) != null) {
    out.println(input);
    System.out.println("Server: " + in.readLine());
    if ("end".equalsIgnoreCase(input)) break;
}
server.close();

進階版:多客戶端併發(外層迴圈)

在 accept() 外層加入 while(true) 迴圈,每次連線建立新 Socket 處理。缺點:同一時間僅能服務一個客戶端,其他需排隊。

專業版:多線程併發架構

public class MultiUserServer extends Thread {
    private Socket client;
    
    public MultiUserServer(Socket client) {
        this.client = client;
    }
    
    public void run() {
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
            PrintWriter out = new PrintWriter(client.getOutputStream(), true);
            
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println("Thread-" + getId() + ": " + line);
                out.println("Received by " + getName());
                if ("end".equalsIgnoreCase(line)) break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try { client.close(); } catch (IOException ignored) {}
        }
    }
    
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(5678);
        System.out.println("Multi-thread server started on 5678");
        while (true) {
            new MultiUserServer(server.accept()).start(); // 每連線一執行緒
        }
    }
}

關鍵技術要點總結

階段核心類別關鍵方法適用場景
基礎通訊Socket, ServerSocketaccept(), getInputStream(), getOutputStream()單一長連線、教學驗證
多客戶排隊ServerSocket + 迴圈while(true) accept()低併發、請求處理極快
多線程併發Thread/Runnable + Socketstart(), run()一般業務、中等併發(<500)
執行緒池ExecutorServicesubmit(), execute()高併發、資源可控、生產環境
NIO 非阻塞Selector, SocketChannelselect(), register()超高併發(萬級)、長連線

實戰最佳實務

  • 資源管理:使用 try-with-resources 確保 Socket/Stream 正確關閉
  • 編碼統一:明確指定 StandardCharsets.UTF_8 避免中文亂碼
  • 逾時控制:socket.setSoTimeout(ms)、server.setSoTimeout(ms) 防止永久阻塞
  • 訊息邊界:TCP 為串流,應用層需定義協定(長度前綴、分隔符、固定長度、序列化)
  • 優雅關閉:實作關閉鉤子、中斷標記、連線清理邏輯
  • 監控指標:連線數、佇列長度、處理延遲、錯誤率

常見坑點避雷

PrintWriter 自動刷新:建構子 new PrintWriter(out, true) 啟用 auto-flush,否則需手動 flush()。
BufferedReader.readLine() 回傳 null:表示對端關閉連線(EOF),非空字串。
InetAddress.getLocalHost() 陷阱:某些環境回傳 127.0.0.1,Client 需指定實際 Server IP。
埠號衝突:1024 以下需權限,建議使用 1024-65535 且避開常用服務埠。

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