2012-01-06 35 views
34

Por lo tanto, estoy tratando de obtener la dirección IP de mi máquina en mi red local (que debe ser 192.168.178.41).Obtener la dirección IP local sin conectarse a Internet

Mi primera intención era utilizar algo como esto:

InetAddress.getLocalHost().getHostAddress(); 

pero sólo devuelve 127.0.0.1, lo cual es correcto pero no muy útil para mí.

Busqué y encontré esta respuesta https://stackoverflow.com/a/2381398/717341, que simplemente crea un Socket -conexión a alguna página web (por ejemplo, "google.com") y obtiene la dirección de host local de la toma:

Socket s = new Socket("google.com", 80); 
System.out.println(s.getLocalAddress().getHostAddress()); 
s.close(); 

Esto funciona para mi máquina (devuelve 192.168.178.41), pero necesita conectarse a Internet para funcionar. Dado que mi aplicación no requiere conexión a Internet y podría parecer "sospechosa" que la aplicación intente conectarse a Google cada vez que se lance, no me gusta la idea de usarla.

Así que, después de más investigación me encontré con la NetworkInterface -class, que (con algo de trabajo) no también devuelve la IP deseada Dirección:

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); 
while (interfaces.hasMoreElements()){ 
    NetworkInterface current = interfaces.nextElement(); 
    System.out.println(current); 
    if (!current.isUp() || current.isLoopback() || current.isVirtual()) continue; 
    Enumeration<InetAddress> addresses = current.getInetAddresses(); 
    while (addresses.hasMoreElements()){ 
     InetAddress current_addr = addresses.nextElement(); 
     if (current_addr.isLoopbackAddress()) continue; 
     System.out.println(current_addr.getHostAddress()); 
    } 
} 

En mi máquina, este devuelve lo siguiente:

name:eth1 (eth1) 
fe80:0:0:0:226:4aff:fe0d:592e%3 
192.168.178.41 
name:lo (lo) 

Encuentra mis dos interfaces de red y devuelve la IP deseada, pero no estoy seguro de qué significa la otra dirección (fe80:0:0:0:226:4aff:fe0d:592e%3).

Además, no he encontrado una manera de filtrarlo de las direcciones devueltas (usando el isXX() -metodos del InetAddress -objeto) y luego usando RegEx, que me parece muy "sucio".

¿Alguna otra idea que no sea usar RegEx o Internet?

+2

fe80: 0: 0: 0: 226: 4AFF: fe0d: 592 sexies se parece a una dirección IPv6 fe80 :: –

+0

'' ... es un IPv6 de enlace local addres s – fge

+0

Y, por cierto, ¿qué quiere "filtrar"? Y, por supuesto, ¿sabes que una máquina puede ser multihomed? – fge

Respuesta

24

fe80: 0: 0: 0: 226: 4aff: fe0d: 592e es su dirección IPv6 ;-).

Marque esta usando

if (current_addr instanceof Inet4Address) 
    System.out.println(current_addr.getHostAddress()); 
else if (current_addr instanceof Inet6Address) 
    System.out.println(current_addr.getHostAddress()); 

Si sólo importa para IPv4, entonces simplemente descarta el caso de IPv6. Pero ten cuidado, IPv6 es el futuro ^^.

P.S .: Compruebe si alguno de sus break s debería haber sido continue s.

+1

'getHostAddress()' está presente en la clase base 'InetAddress', no hay necesidad de enviar contenido aquí (http://docs.oracle.com/javase/6/docs/api/java/net/InetAddress.html#getHostAddress()) – skaffman

+0

Eso se ve muy bien y funciona. Aunque solo para filtrarlos, no necesitas los moldes. Soy consciente de que IPv6 es el futuro, pero para mis necesidades actuales, un IPv4 funcionará bien ;-) Y, por supuesto, tienes razón sobre el 'break's. Lo corregí. ¡Gracias hasta aquí! –

+0

@skaffman: Point taken - cast removed – yankee

2

La respuesta de Yankee es correcta para la primera parte.Para imprimir la dirección IP, se puede obtener como una matriz de bytes y convertir que a la representación normal de cadena como esta:

StringBuilder ip = new StringBuilder(); 
for(byte b : current_addr.getAddress()) { 
    // The & here makes b convert like an unsigned byte - so, 255 instead of -1. 
    ip.append(b & 0xFF).append('.'); 
} 
ip.setLength(ip.length() - 1); // To remove the last '.' 
System.out.println(ip.toString()); 
+0

¿Cuál sería la ventaja con solo usar 'current_addr.getHostAddress()'? –

+0

@Lukas Knuth: Al principio no tenía las impresiones en mi respuesta. Los edité en la publicación un minuto más tarde porque pensé que podría ser bastante útil ;-). Russell probablemente no vio esa versión. – yankee

+0

Vaya, es malo - Supuse que getHostAddress estaba imprimiendo el texto completo que Yankee estaba teniendo que regexar. No noté la impresión anterior de la corriente. –

5
import java.net.*; 

public class Get_IP 
{ 
    public static void main(String args[]) 
    { 
     try 
     { 
      InetAddress addr = InetAddress.getLocalHost(); 
      String hostname = addr.getHostName(); 
      System.out.println(addr.getHostAddress()); 
      System.out.println(hostname); 
     }catch(UnknownHostException e) 
     { 
      //throw Exception 
     } 


    } 

}

+3

Como mencioné anteriormente, esto le da '127.0.0.1' en Linux. Sin embargo, esto podría funcionar con sistemas Windows ... –

+0

se menciona al principio. – Mavlarn

8
public static String getIp(){ 
    String ipAddress = null; 
    Enumeration<NetworkInterface> net = null; 
    try { 
     net = NetworkInterface.getNetworkInterfaces(); 
    } catch (SocketException e) { 
     throw new RuntimeException(e); 
    } 

    while(net.hasMoreElements()){ 
     NetworkInterface element = net.nextElement(); 
     Enumeration<InetAddress> addresses = element.getInetAddresses(); 
     while (addresses.hasMoreElements()){ 
      InetAddress ip = addresses.nextElement(); 
      if (ip instanceof Inet4Address){ 

       if (ip.isSiteLocalAddress()){ 

        ipAddress = ip.getHostAddress(); 
       } 

      } 

     } 
    } 
    return ipAddress; 
} 
+0

este código ignorará la ip 127.0.0.1 en Linux –

+0

¿En qué se diferencia esto de la respuesta y de lo que proporcioné? –

+0

en Linux su código devolverá 127.0.0.1 –

13

Aquí también es un java 8 manera de hacerlo:

public static String getIp() throws SocketException { 

    return Collections.list(NetworkInterface.getNetworkInterfaces()).stream() 
      .flatMap(i -> Collections.list(i.getInetAddresses()).stream()) 
      .filter(ip -> ip instanceof Inet4Address && ip.isSiteLocalAddress()) 
      .findFirst().orElseThrow(RuntimeException::new) 
      .getHostAddress(); 
} 
+1

Esta fue la única solución que me devolvió la dirección IP de LAN. ¡Gracias! – Pali

Cuestiones relacionadas