如何从 Java 枚举所有启用的 NIC 卡的 IP 地址?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/494465/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:20:41  来源:igfitidea点击:

How to enumerate IP addresses of all enabled NIC cards from Java?

javanetworkingip-address

提问by Allain Lalonde

Short of parsing the output of ipconfig, does anyone have a 100% pure java way of doing this?

没有解析 的输出ipconfig,有没有人有 100% 纯 Java 的方法来做到这一点?

采纳答案by Eddie

This is pretty easy:

这很容易:

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)");
}

回答by Jared

Some of this will only work in JDK 1.6 and above (one of the methods was added in that release.)

其中一些仅适用于 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());
      }
   }
}

Prior to 1.6, it's a bit more difficult - isUp() isn't supported until then.

在 1.6 之前,它有点困难 - 在那之前不支持 isUp()。

FWIW: The Javadocsnote that this is the correct approach for getting all of the IP addresses for a node:

FWIW:Javadocs指出这是获取节点所有 IP 地址的正确方法:

NOTE: can use getNetworkInterfaces()+getInetAddresses() to obtain all IP addresses for this node

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

回答by Jay R.

This code only works in Java 1.6 because of the added InterfaceAddress code.

由于添加了 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();
  }

The "toMACAddrString" method looks like this:

“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("%1x", a[i]));

     if (i == iMax)
     {
        return b.append(']').toString();
     }
     b.append(":");
  }
}

and the "toIPAddrString" method is here:

“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();
}

I have that first set of code in the try/catch above in a method called dump() in class called IPConfig. Then I just put a main method in IPConfig to call new IPConfig().dump() so that when I'm trying to figure out some wacky network problem, I can see Java thinks is going on. I figured out that my Fedora box reports different information than Windows for the LocalHost information and it was causing my Java programs some issues.

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

I realize its similiar to the other answers but it prints out nearly everything interesting that you can get from the interface and ipaddress apis.

我意识到它与其他答案相似,但它打印出几乎所有可以从接口和 ipaddress apis 获得的有趣内容。

回答by willtardy

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());
            }
        }
    }

}
}

回答by pds

Update to fix Jared's answer for JDK 1.7.

更新以修复 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;
}

As highlighted by Sam Skuce comment:

正如 Sam Skuce 评论所强调的:

This doesn't compile in JDK 1.7. getNetworkInterfaces returns an Enumeration which does not implement Iterable. – Sam Skuce Jul 11 '12 at 19:58

这不能在 JDK 1.7 中编译。getNetworkInterfaces 返回一个没有实现 Iterable 的枚举。– Sam Skuce 2012 年 7 月 11 日,19:58

Output Example:

输出示例:

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