Socket 類提供豐富的 getter 方法,用於獲取連接的遠端/本地地址信息及輸入輸出流。本文系統梳理這些方法,並說明其在連接生命週期不同階段的可用性。
客戶端連接成功後,可通過以下三種方式獲取服務端 IP 與端口:
Socket socket = new Socket("www.example.com", 80);
InetAddress addr = socket.getInetAddress();
System.out.println("Server IP: " + addr.getHostAddress()); // 如 93.184.216.34
System.out.println("Server Host: " + addr.getHostName()); // 如 www.example.com
int port = socket.getPort(); // 返回 80
返回 SocketAddress(實為 InetSocketAddress),需向下轉型:
SocketAddress remote = socket.getRemoteSocketAddress();
InetSocketAddress isa = (InetSocketAddress) remote;
System.out.println("Host: " + isa.getHostName());
System.out.println("Port: " + isa.getPort());
重要特性:以上三個方法在socket.close()後仍可調用,返回值保持有效。若直接用 IP 連接,getHostName()返回的也是該 IP。
對應本機用於此連接的 IP 與端口:
Socket socket = new Socket();
socket.connect(new InetSocketAddress("www.example.com", 80));
InetAddress local = socket.getLocalAddress();
System.out.println("Local IP: " + local.getHostAddress());
System.out.println("Local Host: " + local.getHostName());
多網卡/多 IP 機器上,返回實際用於建立連接的那張網卡 IP。ADSL 撥號場景下可獲取臨時公網 IP。
int localPort = socket.getLocalPort(); // 系統自動分配的臨時端口
InetSocketAddress localIsa = (InetSocketAddress) socket.getLocalSocketAddress();
System.out.println("Bound IP: " + localIsa.getAddress().getHostAddress());
System.out.println("Bound Port: " + localIsa.getPort());
數據收發的核心入口:
InputStream in = socket.getInputStream();
// 建議包裝為緩衝字符流
BufferedReader br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
String line = br.readLine();
OutputStream out = socket.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
bw.write("Hello Server\r\n");
bw.flush(); // 必須 flush,將緩衝區數據推送至網路
關鍵提醒:
OutputStream預設 8KB 緩衝,flush()才真正發送。- 讀取字符串必須用
BufferedReader.readLine();InputStreamReader無此方法。- 流關閉會導致 Socket 關閉,詳見後續「關閉連接」章節。
| 方法 | 連接前 | 連接後 | 關閉後 |
|---|---|---|---|
| getInetAddress / getPort / getRemoteSocketAddress | null / 0 / null | 有效 | 有效 |
| getLocalAddress / getLocalPort / getLocalSocketAddress | null / -1 / null | 有效 | 有效 |
| getInputStream / getOutputStream | 拋異常 | 有效 | 拋異常 |
掌握這些 getter,能讓你在連接建立、數據傳輸、連接關閉等各階段精確獲取所需上下文信息。