项目中遇到了要获取本地ip的需求,网上查找资料遇到很多坑,很多Java获取本机ip地址的方法要么是根本获取不到,要么是获取的有问题。

网上常见的方法如下

InetAddress.getLocalHost().getHostAddress()

但是如果电脑里面有Lan,WIFI,蓝牙热点,虚拟机网卡,即存在很多的网络接口(network interfaces),每个网络接口就包含一个IP地址,并不是所有的IP地址能被外部或局域网访问,比如说虚拟机网卡地址等等。上面获取到的ip就会有误。

下面是正确的获取ip地址的方法,亲测无误:

方法一:

import java.net.InetAddress;

import java.net.NetworkInterface;

import java.net.UnknownHostException;

import java.util.Enumeration;

public class getRealIp {

public static void main(String[] args) {

try {

// 正确的IP拿法

System.out.println("get LocalHost LAN Address : " + getLocalHostLANAddress().getHostAddress());

} catch (UnknownHostException e) {

e.printStackTrace();

}

}

// 正确的IP拿法,即优先拿site-local地址

private static InetAddress getLocalHostLANAddress() throws UnknownHostException {

try {

InetAddress candidateAddress = null;

// 遍历所有的网络接口

for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {

NetworkInterface iface = (NetworkInterface) ifaces.nextElement();

// 在所有的接口下再遍历IP

for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {

InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();

if (!inetAddr.isLoopbackAddress()) {// 排除loopback类型地址

if (inetAddr.isSiteLocalAddress()) {

// 如果是site-local地址,就是它了

return inetAddr;

} else if (candidateAddress == null) {

// site-local类型的地址未被发现,先记录候选地址

candidateAddress = inetAddr;

}

}

}

}

if (candidateAddress != null) {

return candidateAddress;

}

// 如果没有发现 non-loopback地址.只能用最次选的方案

InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();

if (jdkSuppliedAddress == null) {

throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");

}

return jdkSuppliedAddress;

} catch (Exception e) {

UnknownHostException unknownHostException = new UnknownHostException(

"Failed to determine LAN address: " + e);

unknownHostException.initCause(e);

throw unknownHostException;

}

}

}

这里插上一句,上面的方法之前在java项目中能准确获取到ip,但是放在项目中之后,又不能获取准确的ip,也是很迷,然后又另外找了一种方法,如下:

方法二:

import java.net.Inet4Address;

import java.net.InetAddress;

import java.net.NetworkInterface;

import java.net.SocketException;

import java.util.Enumeration;

/**

* 获取本地真正的IP地址,即获得有线或者无线WiFi地址。

* 过滤虚拟机、蓝牙等地址

*/

public class getRealLocalIP {

public static String getRealIP() {

try {

Enumeration allNetInterfaces = NetworkInterface

.getNetworkInterfaces();

while (allNetInterfaces.hasMoreElements()) {

NetworkInterface netInterface = (NetworkInterface) allNetInterfaces

.nextElement();

// 去除回环接口,子接口,未运行和接口

if (netInterface.isLoopback() || netInterface.isVirtual()

|| !netInterface.isUp()) {

continue;

}

if (!netInterface.getDisplayName().contains("Intel")

&& !netInterface.getDisplayName().contains("Realtek")) {

continue;

}

Enumeration addresses = netInterface

.getInetAddresses();

System.out.println(netInterface.getDisplayName());

while (addresses.hasMoreElements()) {

InetAddress ip = addresses.nextElement();

if (ip != null) {

// ipv4

if (ip instanceof Inet4Address) {

System.out.println("ipv4 = " + ip.getHostAddress());

return ip.getHostAddress();

}

}

}

break;

}

} catch (SocketException e) {

System.err.println("Error when getting host ip address"

+ e.getMessage());

}

return null;

}

}

总之网上比较靠谱的方法就找到这两种,感谢其他博主的博客。

更多推荐