56 votes

java InetAddress.getLocalHost() ; renvoie 127.0.0.1 ... comment obtenir l'IP réelle ?

J'écris une application simple de mise en réseau. J'ai besoin de connaître l'IP réelle de ma machine sur le réseau, comme 192.168.1.3 . getLocalHost renvoie 127.0.0.1 (sous Linux, je ne sais pas si c'est la même chose sous Windows). Comment faire ?

1 votes

Dans mon Windows, System.out.println(InetAddress.getLocalHost().getHostAddress()) ; imprime 10.50.16.136

0 votes

Intéressant ... réponse correcte bien qu'elle ne fonctionne pas ?

0 votes

C'est très courant sur l'OS, la réponse incorrecte est marquée comme répondue.

36voto

Eric Points 1505

Si vous voulez réellement travailler avec toutes les adresses IP de la machine, vous pouvez les obtenir avec la classe NetworkInterface. Bien entendu, vous devez ensuite déterminer celle que vous souhaitez réellement utiliser, mais cela dépendra de l'usage que vous en faites, ou vous devrez peut-être étendre la manière dont vous l'utilisez pour tenir compte des adresses multiples.

import java.net.*;
import java.util.*;

public class ShowInterfaces
{
        public static void main(String[] args) throws Exception
        {
                System.out.println("Host addr: " + InetAddress.getLocalHost().getHostAddress());  // often returns "127.0.0.1"
                Enumeration<NetworkInterface> n = NetworkInterface.getNetworkInterfaces();
                for (; n.hasMoreElements();)
                {
                        NetworkInterface e = n.nextElement();
                        System.out.println("Interface: " + e.getName());
                        Enumeration<InetAddress> a = e.getInetAddresses();
                        for (; a.hasMoreElements();)
                        {
                                InetAddress addr = a.nextElement();
                                System.out.println("  " + addr.getHostAddress());
                        }
                }
        }
}

21 votes

while (x.hasMoreElements()) {} serait plus propre que for (;x.hasMoreElements();) {}

22voto

sfussenegger Points 16204

Comme la machine peut avoir plusieurs adresses, il est difficile de déterminer laquelle est la bonne pour vous. Normalement, vous souhaitez que le système attribue une IP en fonction de sa table de routage. Comme le résultat dépend de l'IP à laquelle vous souhaitez vous connecter, il existe une astuce simple : il suffit de créer une connexion et de voir quelle adresse le système d'exploitation vous a donnée :

// output on my machine: "192.168.1.102"
Socket s = new Socket("192.168.1.1", 80);
System.out.println(s.getLocalAddress().getHostAddress());
s.close();

// output on my machine: "127.0.1.1"
System.out.println(InetAddress.getLocalHost().getHostAddress());

Je ne suis pas sûr qu'il soit possible de le faire sans établir de connexion. Je pense avoir déjà réussi à le faire avec Perl (ou C ?), mais ne me demandez pas ce qu'il en est de Java. Je pense qu'il est possible de créer une socket UDP (DatagramSocket) sans la connecter.

Si un routeur NAT se trouve sur le chemin, vous ne pourrez pas obtenir l'adresse IP que les hôtes distants verront. Cependant, comme vous avez donné 192.* comme exemple, je pense que vous ne vous en souciez pas.

0 votes

Mais comment connaître l'adresse IP de la passerelle (192.168.1.1) pour ouvrir le socket en premier lieu ?

0 votes

@mrod vous devriez utiliser "l'IP à laquelle vous souhaitez vous connecter". Par exemple, vous pouvez utiliser new Socket("www.google.com", 80); pour obtenir l'adresse IP de l'interface qui route vers l'internet

0 votes

Bon, si nous supposons que le cas d'utilisation est la "connexion à un autre hôte", cela fonctionnerait :) . Si le cas d'utilisation est l'audit ou tout autre cas où il n'y a pas de connexion à un autre hôte, je suppose qu'il n'y a pas de 'bonne' adresse IP si plusieurs sont configurées (à moins que nous connaissions un sous-réseau préféré spécifique, par exemple).

18voto

boom boom Points 82

Pour le réparer :

  1. Trouvez votre nom d'hôte. Tapez : hostname . Par exemple, vous trouvez que votre nom d'hôte est mycomputer.xzy.com

  2. Mettez votre nom d'hôte dans votre fichier hosts. /etc/hosts . Par exemple

    10.50.16.136 mycomputer.xzy.com

1 votes

C'est une façon étrange de le "réparer" pour moi : si l'ip hôte de votre application change, vous êtes mort

11voto

boly38 Points 118

Voici un moyen d'éviter les résultats d'IPv6 et de Loopback.

public InetAddress getCurrentIp() {
            try {
                Enumeration<NetworkInterface> networkInterfaces = NetworkInterface
                        .getNetworkInterfaces();
                while (networkInterfaces.hasMoreElements()) {
                    NetworkInterface ni = (NetworkInterface) networkInterfaces
                            .nextElement();
                    Enumeration<InetAddress> nias = ni.getInetAddresses();
                    while(nias.hasMoreElements()) {
                        InetAddress ia= (InetAddress) nias.nextElement();
                        if (!ia.isLinkLocalAddress() 
                         && !ia.isLoopbackAddress()
                         && ia instanceof Inet4Address) {
                            return ia;
                        }
                    }
                }
            } catch (SocketException e) {
                LOG.error("unable to get current IP " + e.getMessage(), e);
            }
            return null;
        }

5voto

chepe lucho Points 704

J'ai écrit ce code :

import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

private String[] getHostAddresses() {
  Set<String> HostAddresses = new HashSet<>();
  try {
    for (NetworkInterface ni : Collections.list(NetworkInterface.getNetworkInterfaces())) {
      if (!ni.isLoopback() && ni.isUp() && ni.getHardwareAddress() != null) {
        for (InterfaceAddress ia : ni.getInterfaceAddresses()) {
          if (ia.getBroadcast() != null) {  //If limited to IPV4
            HostAddresses.add(ia.getAddress().getHostAddress());
          }
        }
      }
    }
  } catch (SocketException e) { }
  return HostAddresses.toArray(new String[0]);
}

Vérifiez-le !

Pour moi :

  • Ça ne doit pas être LoopBack !
  • Il doit être en haut !
  • Doit avoir l'adresse MAC (n'est pas nulle)

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