46 votes

Comment énumérer les adresses IP de toutes les cartes NIC activées à partir de Java ?

Il ne suffit pas d'analyser la sortie de ipconfig Est-ce que quelqu'un a une façon 100% pure java de faire cela ?

53voto

Eddie Points 27755

C'est assez facile :

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

1 votes

Merci pour l'exemple. Il y a cependant un bug (et dans tous les autres exemples ici), getNetworkInterfaces() peut retourner null pour une raison étrange (s'il vous plaît, dites-moi pourquoi) si aucune interface réseau n'est trouvée : 'Returns all the interfaces on this machine. Retourne null si aucune interface réseau n'a pu être trouvée sur cette machine. NOTE : peut utiliser getNetworkInterfaces()+getInetAddresses() pour obtenir toutes les adresses IP pour ce noeud '

1 votes

Version avec LOG.infos remplacée par des appels et importations System out inclus ici : gist.github.com/williamberg/5299998

24voto

Jared Points 7800

Certains de ces éléments ne fonctionneront qu'avec le JDK 1.6 et plus (l'une des méthodes a été ajoutée dans cette version).

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

Avant la version 1.6, c'est un peu plus difficile - isUp() n'est pas supporté avant cette date.

Pour information : le [Javadocs](http://java.sun.com/javase/6/docs/api/java/net/NetworkInterface.html#getNetworkInterfaces()) Notez que c'est l'approche correcte pour obtenir toutes les adresses IP d'un noeud :

NOTE : peut utiliser getNetworkInterfaces()+getInetAddresses() pour obtenir toutes les adresses IP pour ce nœud

0 votes

Selon la JavaDoc, NetworkInterface et ses méthodes ont été ajoutées en 1.4. J'utilise personnellement un code similaire à celui que j'ai posté depuis Java 5, je n'ai donc pas testé mon code avec Java 1.4 ou antérieur.

0 votes

En fait, veuillez modifier votre message afin de supprimer le commentaire erroné "Avant la version 1.6, il n'y a aucun moyen de faire ceci 100% pur java....parsing Runtime results ou JNI seraient vos seules options." car seule la méthode ifUp() que vous avez utilisée a été ajoutée en 1.6. Le reste est présent depuis la 1.4.

1 votes

La classe NetworkInterface est présente depuis la version 1.4, mais les méthodes getInterfaceAddresses() et isUp() sont toutes deux @depuis la version 1.6 (selon java.sun.com/javase/6/docs/api/java/net/NetworkInterface.html ). La 1.6 a rendu la classe NetworkInterface BEAUCOUP plus riche qu'elle ne l'était dans la 1.5.

8voto

Jay R. Points 6337

Ce code ne fonctionne qu'en Java 1.6 à cause de l'ajout du code InterfaceAddress.

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

La méthode "toMACAddrString" ressemble à ceci :

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

et la méthode "toIPAddrString" est ici :

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

J'ai le premier ensemble de code dans le try/catch ci-dessus dans une méthode appelée dump() dans une classe appelée IPConfig. J'ai ensuite ajouté une méthode principale à IPConfig pour appeler new IPConfig().dump(), de sorte que lorsque j'essaie de résoudre un problème de réseau, je peux voir ce que Java pense de ce qui se passe. J'ai découvert que ma boîte Fedora donnait des informations différentes de celles de Windows pour l'information LocalHost et que cela causait des problèmes à mes programmes Java.

Je me rends compte que c'est similaire aux autres réponses mais cela imprime presque tout ce qui est intéressant à partir de l'interface et de l'adresse IP.

0 votes

J'ai un code très similaire dans la procédure de démarrage de mon application. Pour une raison quelconque, RedHat et les Linux apparentés aiment vraiment mal configurer l'adresse de bouclage - j'ai eu d'innombrables problèmes causés par 127.0.0.1 mappé au nom d'hôte plutôt qu'à localhost sur des boîtes Redhat.

0 votes

C'est exactement ce qui me déprime aussi. J'ai fini par mettre du code qui choisit la première interface non-localhost avec une adresse IPv4 et lui demande le nom d'hôte, ou qui permet à l'utilisateur de définir une propriété système qui choisit l'interface par son nom et de définir java.net.preferIPv4.

0 votes

Cela n'a pas nécessairement résolu le problème du nom d'hôte, mais cela signifie que je n'avais plus à dépendre du nom d'hôte.

4voto

pds Points 41

Mise à jour pour corriger la réponse de Jared pour 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;
}

Comme le souligne le commentaire de Sam Skuce :

Cela ne compile pas dans le JDK 1.7. getNetworkInterfaces retourne une Enumeration qui n'implémente pas Iterable. - Sam Skuce 11 Jul '12 à 19:58

Exemple de sortie :

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

1voto

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

}
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X