java.net.Socket 代表客戶端 TCP 通訊端點,封裝了「本地 IP:Port ↔ 遠端 IP:Port」的雙向位元組流通道。單個 Socket 僅能與一台遠端主機通訊;多主機通訊需建立多個 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) | 同上,參數為 InetAddress | IOException, SecurityException | |
protected Socket() | 無連線 Socket,供子類/自定義 SocketImpl 使用 | — | |
protected Socket(SocketImpl impl) | 指定自定義 SocketImpl(穿透防火牆/代理場景) | — |
| 選項 | Getter | Setter | 典型場景 |
|---|---|---|---|
| SO_TIMEOUT | getSoTimeout() | setSoTimeout(ms) | 讀取超時,防死循環 |
| TCP_NODELAY | getTcpNoDelay() | setTcpNoDelay(true) | 關閉 Nagle,低延遲 |
| SO_KEEPALIVE | getKeepAlive() | setKeepAlive(true) | 長連線心跳 |
| SO_RCVBUF | getReceiveBufferSize() | setReceiveBufferSize(size) | 高吞吐調大接收緩衝 |
| SO_SNDBUF | getSendBufferSize() | setSendBufferSize(size) | 高吞吐調大發送緩衝 |
| SO_LINGER | getSoLinger() | setSoLinger(on, seconds) | 優雅關閉控制 |
void close():關閉 Socket,釋放資源,觸發 FIN。建議先 shutdownOutput() 發送完緩衝資料再 close。void shutdownInput() / void shutdownOutput():單向關閉(半關閉),實現協議級「寫完等讀」或「讀完不寫」。
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();
}
}
}
PrintWriter.autoFlush(true) 或手動 flush(),否則資料滯留發送緩衝區。SecurityException 可能阻止連線。Socket 是 Java TCP 客戶端程式設計的核心入口。熟練掌握構造器選擇、I/O 流包裝策略、Socket 選項調優、異常處理與資源管理,能編寫出健壯、高效的網路客戶端程式。