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

Java Socket 類深度解析:構造器、核心方法、連線建立與 I/O 流操作實戰

     編輯:Java 相關知識

Socket 類定位

java.net.Socket 代表客戶端 TCP 通訊端點,封裝了「本地 IP:Port ↔ 遠端 IP:Port」的雙向位元組流通道。單個 Socket 僅能與一台遠端主機通訊;多主機通訊需建立多個 Socket。

核心構造器全景

注意:構造器即發起連線,阻塞直到三次交握完成或超時/失敗。無獨立 connect() 方法(舊版有 connect(SocketAddress) 但較少用)。關鍵業務建議放入獨立執行緒避免 UI 阻塞。

關鍵實例方法分類

I/O 流獲取(核心)

  • InputStream getInputStream():讀取遠端資料,建議包裝 BufferedInputStream/BufferedReader。
  • OutputStream getOutputStream():發送資料,建議包裝 BufferedOutputStream/PrintWriter。

連線資訊查詢

  • InetAddress getInetAddress():遠端 IP。
  • int getPort():遠端埠。
  • InetAddress getLocalAddress():本地綁定 IP。
  • int getLocalPort():本地綁定埠(OS 自動分配臨時埠)。

Socket 選項配置

構造器用途關鍵異常
Socket(String host, int port)最常用:指定主機名/域名與埠,自動解析並連線UnknownHostException, IOException, SecurityException
Socket(InetAddress address, int port)已解析 InetAddress,避免重複 DNS 查詢IOException, SecurityException
Socket(String host, int port, InetAddress localAddr, int localPort)指定本地綁定 IP/埠(多網卡/多 IP 機器必備)UnknownHostException, IOException, SecurityException
Socket(InetAddress address, int port, InetAddress localAddr, int localPort)同上,參數為 InetAddressIOException, SecurityException
protected Socket()無連線 Socket,供子類/自定義 SocketImpl 使用—
protected Socket(SocketImpl impl)指定自定義 SocketImpl(穿透防火牆/代理場景)—
選項GetterSetter典型場景
SO_TIMEOUTgetSoTimeout()setSoTimeout(ms)讀取超時,防死循環
TCP_NODELAYgetTcpNoDelay()setTcpNoDelay(true)關閉 Nagle,低延遲
SO_KEEPALIVEgetKeepAlive()setKeepAlive(true)長連線心跳
SO_RCVBUFgetReceiveBufferSize()setReceiveBufferSize(size)高吞吐調大接收緩衝
SO_SNDBUFgetSendBufferSize()setSendBufferSize(size)高吞吐調大發送緩衝
SO_LINGERgetSoLinger()setSoLinger(on, seconds)優雅關閉控制

生命週期控制

  • void close():關閉 Socket,釋放資源,觸發 FIN。建議先 shutdownOutput() 發送完緩衝資料再 close。
  • void shutdownInput() / void shutdownOutput():單向關閉(半關閉),實現協議級「寫完等讀」或「讀完不寫」。

實戰範例:健壯的 HTTP GET 客戶端


public class SimpleHttpClient {
    public static String get(String host, int port, String path) throws IOException {
        try (Socket socket = new Socket()) {
            // 1. 連線並設定超時
            socket.connect(new InetSocketAddress(host, port), 5000);
            socket.setSoTimeout(10000);
            
            // 2. 發送 HTTP/1.1 請求
            String request = "GET " + path + " HTTP/1.1\r\n" +
                             "Host: " + host + "\r\n" +
                             "Connection: close\r\n" +
                             "User-Agent: SimpleHttpClient/1.0\r\n\r\n";
            try (OutputStream out = socket.getOutputStream();
                 PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, StandardCharsets.ISO_8859_1), true)) {
                writer.print(request);
                writer.flush();
            }
            
            // 3. 讀取回應
            StringBuilder response = new StringBuilder();
            try (InputStream in = socket.getInputStream();
                 BufferedReader reader = new BufferedReader(
                     new InputStreamReader(in, StandardCharsets.ISO_8859_1))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line).append('\n');
                }
            }
            return response.toString();
        }
    }
}

常見坑與最佳實踐

  1. 編碼一致性:網路傳輸位元組流,雙方必須協商字符集(HTTP 預設 ISO-8859-1,現代應用建議显式指定 UTF-8)。
  2. 緩衝區刷新:PrintWriter.autoFlush(true) 或手動 flush(),否則資料滯留發送緩衝區。
  3. 半包/黏包:TCP 無訊息邊界,應用層必須定義協議幀(長度前綴、分隔符、固定長度)。
  4. 資源洩漏:務必使用 try-with-resources 或 finally 關閉流與 Socket。
  5. 安全管理器:Applet/舊版環境下 SecurityException 可能阻止連線。

總結

Socket 是 Java TCP 客戶端程式設計的核心入口。熟練掌握構造器選擇、I/O 流包裝策略、Socket 選項調優、異常處理與資源管理,能編寫出健壯、高效的網路客戶端程式。

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