Java 在不连接到internet的情况下获取本地IP地址

Java 在不连接到internet的情况下获取本地IP地址,java,networking,ip,Java,Networking,Ip,因此,我试图在本地网络中获取我的机器的IP地址(应该是192.168.178.41) 我的第一个意图是使用这样的东西: InetAddress.getLocalHost().getHostAddress(); StringBuilder ip = new StringBuilder(); for(byte b : current_addr.getAddress()) { // The & here makes b convert like an unsigned byte -

因此,我试图在本地网络中获取我的机器的IP地址(应该是
192.168.178.41

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

InetAddress.getLocalHost().getHostAddress();
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());
但它只返回
127.0.0.1
,这是正确的,但对我没有多大帮助

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

Socket s = new Socket("google.com", 80);
System.out.println(s.getLocalAddress().getHostAddress());
s.close();
这确实适用于我的机器(它返回
192.168.178.41
),但它需要连接到internet才能工作。由于我的应用程序不需要互联网连接,而且每次启动应用程序时都试图连接到谷歌可能看起来“可疑”,所以我不喜欢使用它

因此,在进一步研究之后,我偶然发现了
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());
    }
}
它会找到我的两个网络接口并返回所需的IP,但我不确定另一个地址(
fe80:0:0:226:4aff:fe0d:592e%3
)是什么意思

此外,除了使用RegEx之外,我还没有找到从返回的地址中过滤它的方法(通过使用
InetAddress
-对象的
isXX()
-方法),我发现这非常“脏”


除了使用RegEx或internet,还有其他想法吗?

fe80: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是未来的


注意:检查你的一些
中断
S是否应该是
继续
S。

Yankee的答案在第一部分是正确的。要打印出IP地址,可以将其作为字节数组,并将其转换为正常的字符串表示形式,如下所示:

InetAddress.getLocalHost().getHostAddress();
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());
}

公共静态字符串getIp(){
字符串ipAddress=null;
枚举净=空;
试一试{
net=NetworkInterface.getNetworkInterfaces();
}捕获(SocketException e){
抛出新的运行时异常(e);
}
while(net.hasMoreElements()){
NetworkInterface元素=net.nextElement();
枚举地址=element.getInetAddresses();
while(addresses.hasMoreElements()){
InetAddress ip=addresses.nextElement();
if(Inet4Address的ip实例){
如果(ip.isSiteLocalAddress()){
ipAddress=ip.getHostAddress();
}
}
}
}
返回IP地址;
}

这里还有一种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();
}

fe80:0:0:0:226:4aff:fe0d:592e看起来像一个IPv6地址
fe80::…
是一个IPv6链接本地地址,顺便问一下,您想“筛选”什么?当然,您知道机器可以是多宿主的吗?
getHostAddress()
存在于
InetAddress
基类中,不需要在这里强制转换(),它看起来很不错,而且可以工作。虽然只是为了过滤它们,但您不需要强制转换。我知道IPv6是未来的发展趋势,但就我目前的需要而言,IPv4就可以了;-)当然,关于
break
s,你是对的。我改正了。谢谢你一直到这里@yankee:我想没有抓住要点:
if
也没有必要。@skaffmann:没错,在这个例子中,if是毫无意义的,但为了解释如何区分IPv4和IPv6,我不打算改变它。毕竟,问题似乎也是关于提取IPv4地址免责声明:这并不能解释绑定到不同地址的多个网络接口。它将只检索一个,而忽略所有其他。与只使用
当前地址.getHostAddress()
相比,它有什么好处?@Lukas Knuth:起初我的答案中没有指纹。一分钟后我把它们编辑成了帖子,因为我认为这可能会很有帮助;-)。Russell可能没有看到这个版本。哦,我的错-我假设getHostAddress正在打印yankee必须要正则表达式的全文。我没有注意到前面的current打印。正如我前面提到的,这在Linux上为您提供了
127.0.0.1
。但是,这可能适用于Windows系统…首先提到了。这与答案和我提供的有什么不同?返回“192.168.56.1”,但我的LAN地址是“10.0.0.5”。这是唯一返回我实际LAN IP地址的解决方案。非常感谢。
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();
}