J2SE 5.0 引入 InetAddress.isReachable(),提供類似 ping 的主機可達性檢測。本文解析其兩個重載、底層原理、適用場景與局限性。
public boolean isReachable(int timeout) throws IOException
public boolean isReachable(NetworkInterface netif, int ttl, int timeout) throws IOException
false。基於 ICMP Echo Request (ping) 或 TCP Echo 端口 (7) 實現。嘗試建立到目標主機 Echo 服務的連接,成功收到響應返回 true。
| 場景 | 可靠性 | 說明 |
|---|---|---|
| 局域網 (LAN) | 高 | 無防火牆攔截 ICMP/TCP Echo,準確反映主機在線狀態 |
| 互聯網 (Internet) | 低 | 防火牆、路由器常屏蔽 ICMP/TCP Echo 端口,導致誤判為不可達 |
| 跨網段/VPN | 中 | 取決於中間設備是否允許探測包通過 |
建議:僅在受控網路環境 (LAN、數據中心內網) 使用。公網可用性檢測請改用業務層心跳 (HTTP HEAD、自定義 TCP 心跳)。
InetAddress target = InetAddress.getByName("192.168.1.100");
// 簡單探測,3 秒超時
boolean reachable = target.isReachable(3000);
System.out.println("Host reachable: " + reachable);
// 進階:指定網卡 eth0 (索引 1),TTL 10 跳,5 秒超時
NetworkInterface eth0 = NetworkInterface.getByName("eth0");
if (eth0 != null) {
reachable = target.isReachable(eth0, 10, 5000);
System.out.println("Via eth0, TTL=10: " + reachable);
}
IOException:底層網路錯誤(如無權限發送原始套接字、網卡不可用)。isReachable() 提供了輕量級的主機存活探測,但在公網環境受限於網路策略,不可作為服務可用性的唯一判斷依據。生產系統應結合應用層心跳、健康檢查端點綜合評估。