InetAddress.getLocalHost()方法获取本地IP不靠谱
代码
public static void main(String[] args) throws Exception { InetAddress addr = InetAddress.getLocalHost(); System.out.println("Local HostAddress: "+addr.getHostAddress()); String hostname = addr.getHostName(); System.out.println("Local host name: "+hostname); }
mac上输出
原因
在windows环境: 使用InetAddress.getLocalHost()方法看似正常能获得本地ip,实际也有不确定性(多网卡协同工作环境下是不准确的)
Java 的InetAddress.java 调用 InetAddress.java 调用 InetAddressImpl.java 的 public native String getLocalHostName() throws UnknownHostException;来获取本地主机名,是一个系统原生方法和ping hostname 返回的 IP 地址是同一个,并不是 ipconfig 方法得到的 eth0 的IP 地址.
默认情况下本机名是localhost,在host文件中对应的ip是127.0.0.1,所以通过这个函数获取到的ip就是127.0.0.1了
即它就是简单的读取/etc/hosts的内容,所以它默认返回的是127.0.0.1非常的不靠谱,因此本方法十分不建议在生产上使用。
不如我们来看一下 /etc/hosts
/etc/hosts的第一行一般均是:127.0.0.1 localhost,所以返回值是127.0.0.1(倘若你把第一行改为127.1.1.1 localhost,那么它的返回值就是127.1.1.1了)
获取本地IP的靠谱方法
从JDK1.4开始,Java提供了一个NetworkInterface类。这个类可以得到本机所有的物理网络接口和虚拟机等软件利用本机的物理网络接口创建的逻辑网络接口的信息,NetworkInterface可以通过getNetworkInterfaces方法来枚举本机所有的网络接口。我们也可以利用getNetworkInterfaces得到的网络接口来枚举本机的所有IP地址。
NetworkInterface类提供了三个方法可以分别得到网络接口名(getName方法)、网络接口别名(getDisplayName方法)以及和网络接口绑定的所有IP地址(getInetAddresses方法)
代码
windows和linux下通用的获取本机IP的方法
package test; import java.io.IOException; import java.net.*; import java.util.Enumeration; /** * @author yanZhiHang * @date 2023/2/2 11:59 */ public class GetLocalHost { public static void main(String[] args) throws Exception { InetAddress addr = InetAddress.getLocalHost(); System.out.println("Local HostAddress: "+addr.getHostAddress()); String hostname = addr.getHostName(); System.out.println("Local host name: "+hostname); System.out.println("本机ip:" + getIpAddress()); } public static String getIpAddress() { try { //从网卡中获取IP Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces(); InetAddress ip; while (allNetInterfaces.hasMoreElements()) { NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement(); //用于排除回送接口,非虚拟网卡,未在使用中的网络接口 if (!netInterface.isLoopback() && !netInterface.isVirtual() && netInterface.isUp()) { //返回和网络接口绑定的所有IP地址 Enumeration<InetAddress> addresses = netInterface.getInetAddresses(); while (addresses.hasMoreElements()) { ip = addresses.nextElement(); if (ip instanceof Inet4Address) { return ip.getHostAddress(); } } } } } catch (Exception e) { System.err.println("IP地址获取失败" + e.toString()); } return ""; } }