如何用Java确定Internet网络接口

如何解决如何用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,因此这些字段也无济于事。

编程问答问答

在 CSS 中设置 cellpadding 和 cellspacing?
如何在 Java 中创建内存泄漏?
浮点数被破坏了吗?
按字符串属性值对对象数组进行排序
如何加快Android模拟器的速度?
如何舍入至多 2 位小数?
使用 Git 版本控制查看文件的更改历史记录
如何在 JavaScript 中检查空/未定义/空字符串?
微信公众号搜索 “ 程序精选 ” ,选择关注!
微信公众号搜 "程序精选"关注