【问题标题】:How to enumerate IP addresses of all enabled NIC cards from Java?如何从 Java 枚举所有启用的 NIC 卡的 IP 地址?
【发布时间】:2010-10-04 09:56:19
【问题描述】:

没有解析ipconfig的输出,有人有100%纯java的方法吗?

【问题讨论】:

    标签: java networking ip-address


    【解决方案1】:

    这很简单:

    try {
      InetAddress localhost = InetAddress.getLocalHost();
      LOG.info(" IP Addr: " + localhost.getHostAddress());
      // Just in case this host has multiple IP addresses....
      InetAddress[] allMyIps = InetAddress.getAllByName(localhost.getCanonicalHostName());
      if (allMyIps != null && allMyIps.length > 1) {
        LOG.info(" Full list of IP addresses:");
        for (int i = 0; i < allMyIps.length; i++) {
          LOG.info("    " + allMyIps[i]);
        }
      }
    } catch (UnknownHostException e) {
      LOG.info(" (error retrieving server host name)");
    }
    
    try {
      LOG.info("Full list of Network Interfaces:");
      for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
        NetworkInterface intf = en.nextElement();
        LOG.info("    " + intf.getName() + " " + intf.getDisplayName());
        for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
          LOG.info("        " + enumIpAddr.nextElement().toString());
        }
      }
    } catch (SocketException e) {
      LOG.info(" (error retrieving network interface list)");
    }
    

    【讨论】:

    • 感谢您的示例。虽然其中有一个错误(以及此处的所有其他示例),但如果找不到网络接口,getNetworkInterfaces() 可能会出于某种奇怪的原因返回 null(请告诉我原因):'返回这台机器上的所有接口。如果在这台机器上找不到网络接口,则返回 null。注意:可以使用 getNetworkInterfaces()+getInetAddresses() 获取该节点的所有 IP 地址 '
    • 将 LOG.infos 替换为系统输出调用和导入的版本:gist.github.com/williamberg/5299998
    【解决方案2】:

    其中一些仅适用于 JDK 1.6 及更高版本(该版本中添加了其中一种方法。)

    List<InetAddress> addrList = new ArrayList<InetAddress>();
    for(Enumeration<NetworkInterface> eni = NetworkInterface.getNetworkInterfaces(); eni.hasMoreElements(); ) {
       final NetworkInterface ifc = eni.nextElement();
       if(ifc.isUp()) {
          for(Enumeration<InetAddress> ena = ifc.getInetAddresses(); ena.hasMoreElements(); ) {
            addrList.add(ena.nextElement());
          }
       }
    }
    

    在 1.6 之前,这有点困难 - 直到那时才支持 isUp()。

    FWIW:Javadocs 请注意,这是获取节点所有 IP 地址的正确方法:

    注意:可以使用 getNetworkInterfaces()+getInetAddresses() 获取所有 IP 地址 节点

    【讨论】:

    • 根据 JavaDoc,NetworkInterface 及其方法是在 1.4 中添加的。我个人一直在使用与自 Java 5 以来发布的代码类似的代码,因此我没有使用 Java 1.4 或更早版本测试我的代码。
    • 实际上,请编辑您的帖子以删除错误评论“在 1.6 之前,没有办法做到这一点 100% 纯 java....解析运行时结果或 JNI 将是您唯一的选择。 "因为只有您使用的 ifUp() 方法是在 1.6 中添加的。其余的从 1.4 开始就存在。
    • NetworkInterface 类从 1.4 开始存在,但 getInterfaceAddresses() 和 isUp() 方法都是 @since 1.6(根据 java.sun.com/javase/6/docs/api/java/net/NetworkInterface.html)。 1.6 使 NetworkInterface 类比 1.5 更丰富。
    • errr,我明白你在说什么...... getInetAddresses() 是@since 1.4(至少)......在我解决问题时编辑以反映一些疑问:)。跨度>
    • 这不能在 JDK 1.7 中编译。 getNetworkInterfaces 返回一个未实现 IterableEnumeration
    【解决方案3】:

    由于添加了 InterfaceAddress 代码,此代码仅适用于 Java 1.6。

      try
      {
         System.out.println("Output of Network Interrogation:");
         System.out.println("********************************\n");
    
         InetAddress theLocalhost = InetAddress.getLocalHost();
         System.out.println(" LOCALHOST INFO");
         if(theLocalhost != null)
         {
            System.out.println("          host: " + theLocalhost.getHostName());
            System.out.println("         class: " + theLocalhost.getClass().getSimpleName());
            System.out.println("            ip: " + theLocalhost.getHostAddress());
            System.out.println("         chost: " + theLocalhost.getCanonicalHostName());
            System.out.println("      byteaddr: " + toMACAddrString(theLocalhost.getAddress()));
            System.out.println("    sitelocal?: " + theLocalhost.isSiteLocalAddress());
            System.out.println("");
         }
         else
         {
            System.out.println(" localhost was null");
         }
    
         Enumeration<NetworkInterface> theIntfList = NetworkInterface.getNetworkInterfaces();
         List<InterfaceAddress> theAddrList = null;
         NetworkInterface theIntf = null;
         InetAddress theAddr = null;
    
         while(theIntfList.hasMoreElements())
         {
            theIntf = theIntfList.nextElement();
    
            System.out.println("--------------------");
            System.out.println(" " + theIntf.getDisplayName());
            System.out.println("          name: " + theIntf.getName());
            System.out.println("           mac: " + toMACAddrString(theIntf.getHardwareAddress()));
            System.out.println("           mtu: " + theIntf.getMTU());
            System.out.println("        mcast?: " + theIntf.supportsMulticast());
            System.out.println("     loopback?: " + theIntf.isLoopback());
            System.out.println("          ptp?: " + theIntf.isPointToPoint());
            System.out.println("      virtual?: " + theIntf.isVirtual());
            System.out.println("           up?: " + theIntf.isUp());
    
            theAddrList = theIntf.getInterfaceAddresses();
            System.out.println("     int addrs: " + theAddrList.size() + " total.");
            int addrindex = 0;
            for(InterfaceAddress intAddr : theAddrList)
            {
               addrindex++;
               theAddr = intAddr.getAddress();
               System.out.println("            " + addrindex + ").");
               System.out.println("            host: " + theAddr.getHostName());
               System.out.println("           class: " + theAddr.getClass().getSimpleName());
               System.out.println("              ip: " + theAddr.getHostAddress() + "/" + intAddr.getNetworkPrefixLength());
               System.out.println("           bcast: " + intAddr.getBroadcast().getHostAddress());
               int maskInt = Integer.MIN_VALUE >> (intAddr.getNetworkPrefixLength()-1);
               System.out.println("            mask: " + toIPAddrString(maskInt));
               System.out.println("           chost: " + theAddr.getCanonicalHostName());
               System.out.println("        byteaddr: " + toMACAddrString(theAddr.getAddress()));
               System.out.println("      sitelocal?: " + theAddr.isSiteLocalAddress());
               System.out.println("");
            }
         }
      }
      catch (SocketException e)
      {
         e.printStackTrace();
      }
      catch (UnknownHostException e)
      {
         e.printStackTrace();
      }
    

    “toMACAddrString”方法如下所示:

    public static String toMACAddrString(byte[] a)
    {
      if (a == null)
      {
         return "null";
      }
      int iMax = a.length - 1;
    
      if (iMax == -1)
      {
         return "[]";
      }
    
      StringBuilder b = new StringBuilder();
      b.append('[');
      for (int i = 0;; i++)
      {
         b.append(String.format("%1$02x", a[i]));
    
         if (i == iMax)
         {
            return b.append(']').toString();
         }
         b.append(":");
      }
    }
    

    “toIPAddrString”方法在这里:

    public static String toIPAddrString(int ipa)
    {
       StringBuilder b = new StringBuilder();
       b.append(Integer.toString(0x000000ff & (ipa >> 24)));
       b.append(".");
       b.append(Integer.toString(0x000000ff & (ipa >> 16)));
       b.append(".");
       b.append(Integer.toString(0x000000ff & (ipa >> 8)));
       b.append(".");
       b.append(Integer.toString(0x000000ff & (ipa)));
       return b.toString();
    }
    

    我在上面的 try/catch 中有第一组代码,在名为 IPConfig 的类中名为 dump() 的方法中。然后我只是在 IPConfig 中放置一个 main 方法来调用 new IPConfig().dump() 以便当我试图找出一些古怪的网络问题时,我可以看到 Java 认为正在发生的事情。我发现我的 Fedora 机器报告的 LocalHost 信息与 Windows 不同,这导致我的 Java 程序出现了一些问题。

    我意识到它与其他答案类似,但它几乎可以打印出您可以从界面和 ipaddress api 获得的所有有趣内容。

    【讨论】:

    • 我的应用程序的启动过程中有非常相似的代码。出于某种原因,RedHat 和相关的 linux 真的很喜欢错误配置环回地址 - 我遇到了无数问题,原因是 127.0.0.1 被映射到主机名而不是 Redhat 盒子上的 localhost。
    • 这也正是让我失望的原因。我最终输入了选择第一个具有 IPv4 地址的非本地主机接口并询问主机名的代码,或者允许用户设置一个按名称选择接口的系统属性并设置 java.net.preferIPv4
    • 它不一定解决主机名问题,但这意味着我不必再依赖主机名了。
    • InterfaceAddress.getBroadcast() 可能会返回 null
    【解决方案4】:

    更新以修复 Jared 对 JDK 1.7 的回答。

    // Get list of IP addresses from all local network interfaces. (JDK1.7)
    // -----------------------------------------------------------
    public List<InetAddress> getListOfIPsFromNIs(){
        List<InetAddress> addrList           = new ArrayList<InetAddress>();
        Enumeration<NetworkInterface> enumNI = NetworkInterface.getNetworkInterfaces();
        while ( enumNI.hasMoreElements() ){
            NetworkInterface ifc             = enumNI.nextElement();
            if( ifc.isUp() ){
                Enumeration<InetAddress> enumAdds     = ifc.getInetAddresses();
                while ( enumAdds.hasMoreElements() ){
                    InetAddress addr                  = enumAdds.nextElement();
                    addrList.add(addr);
                    System.out.println(addr.getHostAddress());   //<---print IP
                }
            }
        }
        return addrList;
    }
    

    正如 Sam Skuce 评论所强调的那样:

    这在 JDK 1.7 中无法编译。 getNetworkInterfaces 返回一个未实现 Iterable 的枚举。 – Sam Skuce 2012 年 7 月 11 日 19:58

    输出示例:

    fe80:0:0:0:800:aaaa:aaaa:0%8
    192.168.56.1
    fe80:0:0:0:227:aaa:aaaa:6b5%2
    123.123.123.123
    0:0:0:0:0:0:0:1%1
    127.0.0.1
    

    【讨论】:

      【解决方案5】:
      import java.net.*;
      import java.util.*;
      
      public class NIC {
      
      public static void main(String args[]) throws Exception {
      
          List<InetAddress> addrList = new ArrayList<InetAddress>();
          Enumeration<NetworkInterface> interfaces = null;
          try {
              interfaces = NetworkInterface.getNetworkInterfaces();
          } catch (SocketException e) {
              e.printStackTrace();
          }
      
          InetAddress localhost = null;
      
          try {
              localhost = InetAddress.getByName("127.0.0.1");
          } catch (UnknownHostException e) {
              e.printStackTrace();
          }
      
          while (interfaces.hasMoreElements()) {
              NetworkInterface ifc = interfaces.nextElement();
              Enumeration<InetAddress> addressesOfAnInterface = ifc.getInetAddresses();
      
              while (addressesOfAnInterface.hasMoreElements()) {
                  InetAddress address = addressesOfAnInterface.nextElement();
      
                  if (!address.equals(localhost) && !address.toString().contains(":")) {
                      addrList.add(address);
                      System.out.println("FOUND ADDRESS ON NIC: " + address.getHostAddress());
                  }
              }
          }
      
      }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-13
        • 1970-01-01
        • 2010-09-21
        • 2013-08-24
        • 2012-01-07
        • 2013-07-02
        • 2010-12-02
        • 2012-12-02
        相关资源
        最近更新 更多