2012-01-06 155 views
34

所以,我试图让我的机器在我的本地网络(应该是192.168.178.41)的IP地址。获取本地IP地址而无需连接到互联网

我的第一个目的是使用这样的:

InetAddress.getLocalHost().getHostAddress(); 

但它只返回127.0.0.1,这是正确的,但不适合我很大的帮助。

我寻找了一圈,发现这个答案https://stackoverflow.com/a/2381398/717341,它只是创建了一个Socket -connection一些网页(如“google.com”),并得到从插座本地主机地址:

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

这对我的机器有效(它返回192.168.178.41),但它需要连接到互联网才能工作。由于我的应用程序不需要互联网连接,并且它可能看起来应用程序试图在每次启动时连接到谷歌的“可疑”,所以我不喜欢使用它的想法。

于是,经过一些调查研究我穿过NetworkInterface -class,(加上一些工作)不还返回所需的IP地址跌跌撞撞:

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

在我的机器,这将返回以下:

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

它找到我的网络接口并返回所需的IP,但我不确定其他地址(fe80:0:0:0:226:4aff:fe0d:592e%3)是什么意思。

此外,我还没有找到一种方法来从返回的地址(通过使用isXX()-方法InetAddress-对象)过滤它,然后使用正则表达式,我发现它非常“脏”。

除了使用RegEx或互联网以外的其他想法?

+2

FE80:0:0:0:226:4aff:fe0d:592e看起来像一个IPv6地址 – 2012-01-06 23:00:02

+0

'FE80 :: ...'是IPv6链路本地ADDRES s – fge 2012-01-06 23:00:15

+0

顺便说一句,你想“过滤”什么?当然,你知道一台机器可以多宿主吗? – fge 2012-01-06 23:02:01

回答

24

fe80:0:0:0:226:4aff:fe0d:592e是您的ipv6地址;-)。

入住此使用

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

如果你只关心支持IPv4,然后就放弃了IPv6的情况。但要小心,IPv6是未来^^。

P.S .:检查您的某些break应该是continue s。

+1

'getHostAddress()'出现在'InetAddress'基类中,不需要在这里进行转换(http://docs.oracle.com/javase/6/docs/api/java/net/InetAddress.html#getHostAddress ()) – skaffman 2012-01-06 23:13:44

+0

这看起来不错,它的作品。虽然只是为了过滤它们,但不需要剧组。我知道IPv6是未来,但对于我目前的需求,IPv4可以做得很好;-)当然,你对“break”是正确的。我纠正了这一点。谢谢,直到这里! – 2012-01-06 23:15:37

+0

@skaffman:采取的点 - 被删除 – yankee 2012-01-06 23:37:54

2

Yankee的答案对第一部分是正确的。要打印出来的IP地址,你可以把它作为一个字节数组,将其转换成正常的字符串表示这样的:

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

仅仅使用'current_addr.getHostAddress()'会有什么优势? – 2012-01-06 23:18:11

+0

@Lukas Knuth:起初我没有在我的答案打印。我在一分钟后将它们编辑为帖子,因为我认为这可能相当有用;-)。罗素可能没有看到那个版本。 – yankee 2012-01-06 23:40:09

+0

哎呀,我的坏 - 我认为getHostAddress打印出了严格的正则表达式的全文。我没有注意到当前的早期版画。 – 2012-01-07 00:11:33

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

正如我上面提到的,这给你在Linux上的'127.0.0.1'。但是,这可能适用于Windows系统...... – 2012-02-01 18:19:25

+0

它首先被提及。 – Mavlarn 2013-12-17 01:37:53

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

此代码将忽略Linux中的127.0.0.1 ip – 2013-09-22 15:41:47

+0

这与答案和我提供的内容有什么不同? – 2013-09-22 16:21:15

+0

在你的代码将返回127.0.0.1 – 2013-09-23 06:44:28

13

这里也是一个java这样做的8路:

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

这是唯一的解决方案,返回我的实际LAN IP地址。谢谢! – Pali 2015-12-07 19:54:04