如何可靠地找到本地 IP 地址?

乍一看很容易。 只需调用 InetAddress.getLocalHost() 即可获取本地 IP 地址。 但是,当机器上有虚拟接口时,此方法将不会返回正确的 IP 地址。

比如一台安装了vmware的机器,ipconfig列出的IP地址至少有3个:

无线 LAN 适配器无线网络连接 4:

     Connection-specific DNS Suffix . : gateway.2wire.net
     Link-local IPv6 Address . . . . . : fe80::2d6b:91f7:5bdd:7103%21
     IPv4 Address. . . . . . . . . . . : 192.168.2.100
     Subnet Mask . . . . . . . . . . . : 255.255.255.0
     Default Gateway . . . . . . . . . : 192.168.2.1

Ethernet adapter VMware Network Adapter VMnet1:

     Connection-specific DNS Suffix . :
     Link-local IPv6 Address . . . . . : fe80::c53a:65e3:112:731%16
     IPv4 Address. . . . . . . . . . . : 192.168.172.1
     Subnet Mask . . . . . . . . . . . : 255.255.255.0
     Default Gateway . . . . . . . . . :

Ethernet adapter VMware Network Adapter VMnet8:

     Connection-specific DNS Suffix . :
     Link-local IPv6 Address . . . . . : fe80::2119:1d74:2a9e:2c25%17
     IPv4 Address. . . . . . . . . . . : 192.168.79.1
     Subnet Mask . . . . . . . . . . . : 255.255.255.0
     Default Gateway . . . . . . . . . :

在上面的例子中,VMnet1 和 VMnet8 是 vmware 软件创建的虚拟接口。
InetAddress.getLocalHost()方法返回192.168.172.1,属于连接状态为“无网络访问”的VMnet1接口。 显然,如果在 RMI 存根中使用本地地址,这是不正确的,这将导致无法路由的 RMI 调用。 如果我们使用java.net.NetworkInterface中的isVirtual()方法来检查VMnet1和VMnet8是否是虚拟接口,发现它们都不是虚拟接口也是令人失望的。 所以在 Java 中没有办法真正排除那些虚拟接口。

最可靠的方法是使用路由表。 在 Windows 上,“route print”命令给我们类似的东西:

网络 Destination                         Netmask                         Gateway                         Interface                         Metric
                      0.0.0.0                           0.0.0.0                     192.168.2.1                  192.168.2.100                       25
                  127.0.0.0                       255.0.0.0                             On-link                          127.0.0.1                       306
            192.168.79.1           255.255.255.255                             On-link                    192.168.79.1                       276
          192.168.172.1           255.255.255.255                             On-link                  192.168.172.1                       276

我们可以看到默认路由使用接口 192.168.2.100。

在 linux 上,我们可以在 /proc/net/route 中查看路由表

在此示例中,我们可以看到默认路由使用接口 p3p1。

我创建了 ParseRoute 类来从路由表中检索本地 IP 地址和默认网关信息。 Windows下解析路由表的代码:

linux上解析路由表的代码:

使用示例:

你可以在这里下载源代码。 或者在线查看主类:ParseRoute.java

如果您有任何问题,请随时联系sales@ireasoning.com.cn


标签: SNMP 服务, WINDOWS
京公网安备 11010802041589号    |    备案号:京ICP备09015132号-1021