无需连接到互联网即可获取本地IP地址

时间:2012-01-06 22:56:38

标签: java networking ip

所以,我正在尝试在我的本地网络中获取我的机器的IP地址(应该是192.168.178.41)。

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

InetAddress.getLocalHost().getHostAddress();

但它只会返回127.0.0.1,这对我来说是正确但不是很有用。

我四处搜索并找到了这个答案https://stackoverflow.com/a/2381398/717341,它只是创建一个Socket - 与某个网页(例如“google.com”)的连接,并从套接字获取本地主机地址:

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

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

所以,经过一些更多的研究后,我偶然发现了NetworkInterface - 类,其中(有一些工作)也会返回所需的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,我发现非常“脏”。

除了使用RegEx或互联网之外还有其他想法吗?

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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();
}

答案 2 :(得分: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;
}

答案 3 :(得分: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());