欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java 获取主机ip地址(ipv4)

程序员文章站 2024-02-14 15:13:28
...

在java 应用中, 有时需要获取应用所在服务器的ip地址, 比如说利用Zookeeper 做动态节点上下线时。 java 提供了InetAddress 类来获取主机ip地址, 但是使用的时候需要注意一下细节问题。

1. InetAddress

直接使用InetAddress 的getLocalHost()方法, 获取到的Ip 地址与本机hosts 的配置有关。 如果是linux 环境的话, 其实获取的就是命令: hostname -i 返回的ip地址, 而具体hostname -i 返回值是什么, 取决于/etc/hosts 配置文件的配置。

1.1 测试代码

    public static void main(String[] args) throws UnknownHostException {

        // 直接通过InetAddress.getLocalHost()方法获取的ip地址, 其实就是执行hostname -i 得到的ip地址
        InetAddress inetAddress = InetAddress.getLocalHost();

        System.out.println("ip 地址:" + inetAddress.getHostAddress() + ", 是否是回环网卡: " + inetAddress.isLoopbackAddress());
    }

1.2 主机名映射地址设置为回环网卡地址

  1. 编辑/et/hosts 文件
127.0.0.1	zongf-PC
  1. 执行hostname 命令
[email protected]:~$ hostname -i
127.0.0.1
  1. 执行java 测试类
ip 地址:127.0.0.1, 是否是回环网卡: true

1.3 主机名映射地址设置为非回环网卡地址

  1. 编辑/etc/hosts 文件, 添加域名映射规则。 笔者主机名为zongf-PC
192.168.0.1	zongf-PC
  1. 执行hostname 命令
$ hostname -i
192.168.0.1
  1. 执行java 测试类
ip 地址:192.168.0.1, 是否是回环网卡: false

2. 获取主机ip 工具类

从上面测试可以看出, 若想获取应用所在服务器的真实ip地址, 单单通过InetAddress 是不可以的。 我们可以配合NetworkInterface 接口来实现, 因此笔者写了一个获取地址的 工具类, 此工具类获取地址方式:

  1. 首先获取hosts 文件中配置主机名映射的地址, 相当于hostname -i 的返回结果
  2. 如果返回地址不是127.0.0.1,则直接返回; 否则获取ipv4 网卡设置的地址。
public class InetAddressUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(InetAddressUtil.class);

    /** 获取主机地址 */
    public static String getHostIp(){

        String realIp = null;

        try {
            InetAddress address = InetAddress.getLocalHost();

            // 如果是回环网卡地址, 则获取ipv4 地址
            if (address.isLoopbackAddress()) {
                address = getInet4Address();
            }

            realIp = address.getHostAddress();

            LOGGER.info("获取主机ip地址成功, 主机ip地址:{}", address);
            return address.getHostAddress();
        } catch (Exception e) {
            LOGGER.error("获取主机ip地址异常", e);
        }

        return realIp;
    }

    /** 获取IPV4网络配置 */
    private static InetAddress getInet4Address() throws SocketException {
        // 获取所有网卡信息
        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
        while (networkInterfaces.hasMoreElements()) {
            NetworkInterface netInterface = (NetworkInterface) networkInterfaces.nextElement();
            Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
            while (addresses.hasMoreElements()) {
                InetAddress ip = (InetAddress) addresses.nextElement();
                if (ip instanceof Inet4Address) {
                    return ip;
                }
            }
        }
        return null;
    }
}