如何解决如何用Java确定Internet网络接口?
开发过程中遇到如何用Java确定Internet网络接口的问题如何解决?下面主要结合日常开发的经验,给出你关于如何用Java确定Internet网络接口的解决方法建议,希望对你解决如何用Java确定Internet网络接口有所启发或帮助;问题描述
在我的笔记本电脑上(运行windows 7,安装了Virtual Box及其网络接口),以下代码将打印出我的无线接口的名称以及本地地址。它在一天结束时使用暴力手段,但只会尝试并实际连接到被认为是最佳候选人的地址。
// iterate over the network interfaces kNown to java
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
OUTER : for (NetworkInterface interface_ : Collections.List(interfaces)) {
// we shouldn't care about loopback addresses
if (interface_.isLoopback())
continue;
// if you don't expect the interface to be up you can skip this
// though it would question the usability of the rest of the code
if (!interface_.isUp())
continue;
// iterate over the addresses associated with the interface
Enumeration<InetAddress> addresses = interface_.getInetAddresses();
for (InetAddress address : Collections.List(addresses)) {
// look only for ipv4 addresses
if (address instanceof Inet6Address)
continue;
// use a timeout big enough for your needs
if (!address.isReachable(3000))
continue;
// java 7's try-with-resources statement, so that
// we close the socket immediately after use
try (SocketChannel socket = SocketChannel.open()) {
// again, use a big enough timeout
socket.socket().setSoTimeout(3000);
// bind the socket to your local interface
socket.bind(new InetSocketAddress(address, 8080));
// try to connect to *somewhere*
socket.connect(new InetSocketAddress("Google.com", 80));
} catch (IOException ex) {
ex.printstacktrace();
continue;
}
System.out.format("ni: %s, ia: %s\n", interface_, address);
// stops at the first *working* solution
break OUTER;
}
}
(我已isReachable(...)
根据MockerTim的答案更新了我的答案。)
需要注意的一件事。socket.bind(...)
如果我尝试连续太快地运行我的代码(例如连接清理得不够快),就会对我说地址和端口已经被使用了。8080
应该是一个随机端口。
解决方法
您如何确定使用Java的哪个网络接口连接到Internet?例如,我跑步
InetAddress.getLocalHost().getHostAddress();
在Eclipse中,这恰好返回了我想要的值192.168.1.105。但是,如果我将此文件打包到jar文件中并运行程序,则代码将返回169.254.234.50。对此进行调查后,我发现这是机器上的VMware虚拟以太网适配器接口的IP地址。
有什么方法可以确定连接到Internet的接口,但同时又可以保持我代码的可移植性?
接口比较
接口[net4]
display name : Intel(R) Centrino(R) Ultimate-N 6300 AGN
MTU : 1500
loopback : false
point to point: false
up : true
virtual : false
multicast : true
HW address : 00 24 D7 2C 5F 70
INET address (IPv4): 192.168.1.105
host name : MyComputer
canonical host name : MyComputer
loopback : false
site local : true
any local : false
link local : false
multicast : false
reachable : true
接口[eth5]
display name : VMware Virtual Ethernet Adapter for VMnet1
MTU : 1500
loopback : false
point to point: false
up : true
virtual : false
multicast : true
HW address : 00 50 56 C0 00 01
INET address (IPv4): 169.254.234.50
host name : MyComputer
canonical host name : MyComputer
loopback : false
site local : false
any local : false
link local : true
multicast : false
reachable : true
第三个VMware界面的站点为local = true,链接为local = false,因此这些字段也无济于事。