【发布时间】:2018-05-16 09:56:41
【问题描述】:
我尝试使用 Java 查找我的 PC 的本地 IP 地址。然而,结果并不正确。具体来说,我需要来自ipconfig 命令的无线局域网适配器WiFi IPv4 地址。我查看了许多不同的问题,例如this excellent answer,但不清楚如何在 Java 中做到这一点。 InetAddress.getLocalHost() 返回错误的 IP('Ethernet-Adapter VirtualBox Host-Only Network')。
我尝试了以下代码:
public static List<String> getLocalIPAddresses() throws Exception
{
val networkInterfaces = NetworkInterface.getNetworkInterfaces();
val localIPAddresses = new ArrayList<String>();
while (networkInterfaces.hasMoreElements())
{
for (val interfaceAddress : networkInterfaces.nextElement().getInterfaceAddresses())
{
val address = interfaceAddress.getAddress();
// Find the local IP addresses
if (address.isSiteLocalAddress())
{
val localIPAddress = interfaceAddress.getAddress().toString().replace("/", "");
localIPAddresses.add(localIPAddress);
}
}
}
if (localIPAddresses.isEmpty())
{
throw new IllegalStateException("Expected the computer's local IP address but didn't get one!");
}
return localIPAddresses;
}
注意:val 来自Lombok。
在我的机器上,这会返回一个包含 2 个 IP 地址的列表:
192.168.56.1
192.168.2.103
“以太网适配器 VirtualBox 仅主机网络”一个和正确的“无线 LAN 适配器 WiFi”一个。我能做些什么来始终保证后者?显然检查 isSiteLocalAddress()(又名本地 IP 地址)是不够的。代码方面还能做什么?过滤掉“VirtualBox”并不是万无一失的解决方案,尤其是因为网络接口名称取决于语言:
public static List<String> getLocalIPAddresses() throws Exception
{
val networkInterfaces = NetworkInterface.getNetworkInterfaces();
val localIPAddresses = new ArrayList<String>();
while (networkInterfaces.hasMoreElements())
{
val networkInterface = networkInterfaces.nextElement();
val displayName = networkInterface.getDisplayName();
if (!displayName.contains("VirtualBox"))
{
for (val interfaceAddress : networkInterface.getInterfaceAddresses())
{
val address = interfaceAddress.getAddress();
// Find the local IP addresses
if (address.isSiteLocalAddress())
{
val localIPAddress = interfaceAddress.getAddress().toString().replace("/", "");
localIPAddresses.add(localIPAddress);
}
}
}
}
if (localIPAddresses.isEmpty())
{
throw new IllegalStateException("Expected the computer's local IP address but didn't get one!");
}
return localIPAddresses;
}
我需要一个独立于平台的解决方案。不过我在 Windows 上。
【问题讨论】:
-
是否在同一个网络接口上找到了两个 IP?如果不是,你能用networkIntreface.isVirtual()等布尔测试来区分接口吗?
-
@MichaelMcKay:即使在包含
isVirtual()检查代码后仍然返回 2 个 IP。它们各自位于不同的网络接口上。 -
如果“InetAddress.getLocalHost() 返回错误的 IP”,你能用它在你的 for 循环中过滤掉它吗?
-
@MichaelMcKay:不,因为对于另一台机器它可能是正确的......
-
我唯一可以建议的另一件事是使用 getName() 方法并选择第一个以“wlan”开头的方法。最后,这两个 IP 地址都是对“我的 IP 地址是什么?”问题的有效答案。 - 不是误报。您可以使用 Windows 中的主机文件来指定选择哪个作为默认值,但该文件可能在许多计算机上不存在。您还可以查看命名服务。
标签: java networking ip ipv4