Cav*_*len 13 java networking network-interface
如何确定使用Java连接到Internet的网络接口?例如,我跑
InetAddress.getLocalHost().getHostAddress();
Run Code Online (Sandbox Code Playgroud)
在Eclipse中,这完全返回我想要的内容,192.168.1.105.但是,如果我将其打包到jar文件并运行该程序,则代码返回169.254.234.50.看看这个,我发现这是我机器上的VMware虚拟以太网适配器接口的IP地址.
有没有办法确定连接到互联网的接口,但同时保持我的代码的可移植性?
接口比较
界面[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
Run Code Online (Sandbox Code Playgroud)
界面[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
Run Code Online (Sandbox Code Playgroud)
还有第三个VMware接口,其中site local = true且link local = false,因此这些字段也没有任何帮助.
Koh*_*ert 20
在我的笔记本电脑上(运行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;
}
}
Run Code Online (Sandbox Code Playgroud)
(我isReachable(...)根据Mocker Tim的回答更新了我的答案.)
有一点需要注意.socket.bind(...)如果我试图连续快速地运行我的代码,就像连接没有足够快地清理那样,地址和端口已经在使用,我会咆哮我.8080应该是一个随机端口.
如果有多个已启动并运行的网络接口,则必须以编程方式选择程序应使用的网络接口.
更新:
我发现了与你相似的问题.
请参阅如何检查如何检查互联网连接是否存在于java中的答案.
更新2:
恕我直言你应该在你的程序中执行以下操作: