JDK 1.4 引入 java.net.NetworkInterface,統一提供物理網卡、虛擬網卡(VMware、Docker、VPN 等)及邏輯介面(回環、PPP、IPv6 隧道)的信息查詢能力。本文系統講解創建對象、枚舉所有介面、核心 getter 方法及實戰應用。
介面名由作業系統分配,常見格式:
eth0, eth1, lo (回環)以太網, WLAN, 本地連接* 等顯示名,或內部名如 eth0 (視驅動而定)ppp0, tun0NetworkInterface ni = NetworkInterface.getByName("eth0");
if (ni == null) System.out.println("介面不存在");
else System.out.println(ni); // toString() 輸出 name, displayName, 綁定 IPs
確定某個本地 IP 所屬介面。**參數必須是本地 IP**,遠程 IP 會返回 null。
InetAddress localIp = InetAddress.getByName("192.168.1.100");
NetworkInterface ni = NetworkInterface.getByInetAddress(localIp);
// 返回綁定該 IP 的介面 (如 eth0)
ADSL 撥號 IP 通常屬於 ppp0 介面。
Enumeration nis = NetworkInterface.getNetworkInterfaces();
while (nis.hasMoreElements()) {
NetworkInterface ni = nis.nextElement();
System.out.println(ni); // 打印完整信息
// 或按需提取
System.out.println("Name: " + ni.getName());
System.out.println("Display: " + ni.getDisplayName());
Enumeration ips = ni.getInetAddresses();
while (ips.hasMoreElements()) {
System.out.println(" IP: " + ips.nextElement().getHostAddress());
}
}
name:lo (MS TCP Loopback interface) index:1
IP: 127.0.0.1
IP: 0:0:0:0:0:0:0:1 (::1)
name:eth0 (Realtek RTL8139 Family PCI Fast Ethernet NIC) index:4
IP: 192.168.18.10
IP: 192.168.18.20
name:ppp0 (WAN (PPP/SLIP) Interface) index:0
IP: 218.61.151.22 (ADSL 動態公網 IP)
name:VMware Network Adapter VMnet1 index:5
IP: 192.168.83.1
name:VMware Network Adapter VMnet8 index:6
IP: 192.168.189.1
| 方法 | 返回值 | 說明 |
|---|---|---|
getName() | String | 系統內部名 (eth0, lo, ppp0...) |
getDisplayName() | String | 友好顯示名 (Windows 下為網卡描述,Unix 下常同 getName) |
getInetAddresses() | Enumeration<InetAddress> | 該介面綁定的所有 IP (IPv4 + IPv6) |
getIndex() | int | 介面索引 (內核分配) |
isUp() | boolean | 介面是否啟用 |
isLoopback() | boolean | 是否回環介面 |
isPointToPoint() | boolean | 是否點對點 (PPP, VPN) |
supportsMulticast() | boolean | 是否支持組播 |
getHardwareAddresses() | byte[] (MAC) | 物理地址 (MAC),虛擬介面可能為空 |
getMTU() | int | 最大傳輸單元 |
getSubInterfaces() | Enumeration<NetworkInterface> | 子介面 (VLAN, IP 別名等) |
Socket.bind() 或 ServerSocket.bind()。isReachable(netif, ...)。ni.getHardwareAddresses() (需過濾虛擬介面)。docker0, veth*, cni0 等虛擬介面。public static InetAddress getPrimaryIpv4() throws SocketException {
Enumeration nis = NetworkInterface.getNetworkInterfaces();
while (nis.hasMoreElements()) {
NetworkInterface ni = nis.nextElement();
if (ni.isLoopback() || !ni.isUp() || ni.isPointToPoint()) continue;
Enumeration ips = ni.getInetAddresses();
while (ips.hasMoreElements()) {
InetAddress ip = ips.nextElement();
if (ip instanceof Inet4Address) return ip; // 找到第一個 IPv4
}
}
return null;
}
SocketPermission "resolve" 權限 (SecurityManager 環境下)。isPointToPoint()、displayName 關鍵字。getInetAddresses() 中,需用 instanceof Inet6Address 區分。