知道InetAddress.getLocalHost()方法是可以获取本地ip的,但是在mac电脑上执行的时候,偶尔会得到127.0.0.1的输出,这样拿到本地ip很不稳定,感觉就很不靠谱了

目录

  • InetAddress.getLocalHost()方法获取本地IP不靠谱
    • 原因
  • 获取本地IP的靠谱方法
    • 代码
    • 避坑
      • 注意代码中是返回和网络接口绑定的所有IP地址
      • 解决

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 调用 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 {//从网卡中获取IPEnumeration<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 "";}
}

避坑

注意代码中是返回和网络接口绑定的所有IP地址

⚠️我这边服务器有docker容器,结果根据上述代码获取本地IP的时候,获取的是docker对外的网卡ip,结果导致获取先获取到了docker对外的网卡ip。同时也有可能存在多个网卡,影响获取真正的IP

解决

因为我真实目的是校验输入的IP是否为本机ip,所以只要证明网络接口中的所有IP包含输入的IP即可

改造后的代码

    public static boolean isLocalHost(String localHost) throws Exception {try {Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();while (allNetInterfaces.hasMoreElements()) {NetworkInterface netInterface = allNetInterfaces.nextElement();if (!netInterface.isLoopback() && !netInterface.isVirtual() && netInterface.isUp()) {Enumeration<InetAddress> addresses = netInterface.getInetAddresses();while (addresses.hasMoreElements()) {InetAddress ip = addresses.nextElement();if (null != ip && ip.getHostAddress().contains(localHost)) {return true;}}}}} catch (Exception e) {log.error("校验IP地址失败:", e.getCause());e.printStackTrace();throw new Exception(e);}return false;}

参考
java获取本机IP

java:获取本机IP,Linux环境下使用InetAddress.getLocalHost()方法获得127.0.0.1相关推荐

  1. 用java获取本机IP地址

    在网上找了几个用java获取本机IP地址的代码,发现都少都有些不完美,自己整理了一下.突然之间很想把自己的IP地址给获取了,虽然用系统自带命令可以得到,但自己想写一个程序获取一下,到网上搜索了一下ja ...

  2. linux 环境启动redis,linux环境下启动redis的方法

    linux环境下启动redis的方法 发布时间:2020-08-24 16:15:54 来源:亿速云 阅读:88 作者:小新 这篇文章主要介绍了linux环境下启动redis的方法,具有一定借鉴价值, ...

  3. java获取本机IP

    如果是在windows环境: 使用InetAddress.getLocalHost()方法即可. import java.net.InetAddress;public class Main {publ ...

  4. java获取本机ip地址_代码片段:获取系统所有IP

    问题 在Windows系统中,可以支持多个网卡,比如有线的以太网卡,无线网卡,虚拟网卡等.如下图所示: 每一张网卡由不同的类型,也可以分别被用户启用或禁用. 对于单独一张给定的网卡,其IP地址可以是D ...

  5. linux环境下可执行文件,提示libboost_thread.so.1.71.0: cannot open shared object file: No such file or directory

    在linux环境下执行可执行文件时,提示这个错误error while loading shared libraries: libboost_thread.so.1.71.0: cannot open ...

  6. java jni linux_java jni实现linux环境下绑定硬件的License

    由于系统运行在Linux环境中,该License绑定服务器的cpuid和mac等信息,而java实现起来不太方便所以就利用了JNI 问题及解决方法: 1.System.loadLibrary(&quo ...

  7. JAVA 获取本机IP(包括 内网IP 和 公网IP)

    Spring 获取客户端请求 IP,详见:https://blog.csdn.net/NRlovestudy/article/details/90900925 本文获取的是 项目所在系统的IP(本地I ...

  8. java获取本机ip和本机公网ip

    话不多少,有用请点赞 本机ip public static String getIpAddr(HttpServletRequest request) {if (request == null) {re ...

  9. java获取本机IP,系统随机分配端口号,获取当前线程ID

    ServerSocket serverSocket = null; //读取空闲的可用端口 String localIp = null; try {serverSocket = new ServerS ...

最新文章

  1. ubuntu开机出现:system program problem detected
  2. java 时间与字符串之间的转换
  3. php 组装二维数组,php实现快速对二维数组某一列进行组装的方法小结
  4. Opencv——图像金字塔与图像尺寸缩放
  5. Python入门--try-except-else
  6. hdu 1074 Doing Homework
  7. Android仿IOS有弹性ScrollView
  8. 【U8】出纳管理制单锁定
  9. 2019ICPC南京区域赛ABCHIJK
  10. js 经纬度坐标转换
  11. opencv4 QR码检测和识别源码解析
  12. Android(15)——ButterKnife
  13. 把SD卡制作为启动卡的操作步骤
  14. 楼道灯人体红外感应电路(半波式)
  15. 不可告人的隐私百度云_理解围绕软件技术标准的不可告人的动机和力量
  16. 推荐系统-推荐引擎的架构
  17. 和ASP.NET AJAX应用程序环游地球
  18. 【小米盒子1代 (MDZ-05-AA)版本降级完美教程】
  19. 基于LTC1068的程控滤波器
  20. php+mysql 商品报价系统 学生适用

热门文章

  1. HTML5历史状态管理history API-pushState/replaceState与popstate事件
  2. ArcGIS教程:创建饼图
  3. VSCODE的Python配置
  4. 模糊数学Fuzzy Set第1讲——Classic Fuzzy Set: Theory and Applications
  5. 联想LJ2400激光打印机开机4灯闪烁维修分析
  6. wifi 的几种加密方式
  7. matlab scope 多个图,matlab scope论文画图
  8. viewsets.ModelViewSet
  9. cadence allegro 17.2中的正负片
  10. Unity 支持 3ds max 2021 物理材质吗?(FBX 出口)是否应该使用BPR材质?