在Java中,我想找到与所使用的接口相对应的java.net.NetworkInterface到达默认网关。接口的名称等不是提前知道的。
换句话说,如果以下是我的路由表,我希望接口对应“bond0”:
$ netstat -r
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
10.10.10.0 * 255.255.255.0 U 0 0 0 bond0
10.10.11.0 * 255.255.255.0 U 0 0 0 eth2
10.10.11.0 * 255.255.255.0 U 0 0 0 eth3
10.10.12.0 * 255.255.255.0 U 0 0 0 eth4
10.10.13.0 * 255.255.255.0 U 0 0 0 eth5
default mygateway 0.0.0.0 UG 0 0 0 bond0
在做了一些谷歌搜索后,我仍然没有找到任何答案。
修改
java运行时必须“知道”如何获取此信息(并不是说它已暴露)。当使用join(InetAddress grpAddr)调用(未指定接口)将java.net.MulticastSocket连接到多播组时,明显的行为似乎是在“默认”接口上加入(如上所述)。即使默认的intf不是路由表中列出的第一个接口,这也可以工作。但是,加入mcast组的基础POSIX调用需要此信息!:
struct ip_mreqn group;
group.imr_multiaddr = ...
group.imr_address = **address of the interface!**
setsockopty(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group));
要点:通过提供一种加入不需要intf的组播组的方法,java平台隐式地必须知道如何在每个平台上确定合适的intf。
答案 0 :(得分:5)
我的方式是:
try(DatagramSocket s=new DatagramSocket())
{
s.connect(InetAddress.getByAddress(new byte[]{1,1,1,1}), 0);
return NetworkInterface.getByInetAddress(s.getLocalAddress()).getHardwareAddress();
}
由于使用了数据报(UDP),它没有连接到任何地方,因此端口号可能毫无意义,远程地址(1.1.1.1
)无需可访问,只是可路由。
答案 1 :(得分:0)
据我所知,没有好的方法可以做到这一点,因为Java以跨平台的方式实现这些低级细节非常困难。 java.net.NetworkInterface可能会有所帮助,但如果可用的方法不够,你可能不得不诉诸一些更丑陋的东西。
这是永远在指定平台上运行的东西,还是需要更便携?在最坏的情况下,您可以尝试执行系统命令并解析输出,但这不是非常便携或稳定。
一些相关主题:
Is it possible to get the default gateway IP and MAC addresses in java?