Java 实例 – 获取指定主机的IP地址(超详细)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

在 Java 开发中,网络编程是一个常见的需求场景,而获取指定主机的 IP 地址是其中的基础操作。无论是构建分布式系统、实现网络监控工具,还是开发需要与远程服务交互的应用程序,掌握这一技能都能显著提升开发效率。本文将通过循序渐进的方式,从网络基础概念到具体代码实现,结合实际案例,深入浅出地讲解如何在 Java 中获取指定主机的 IP 地址。


网络基础:IP 地址与 DNS 的关系

在开始编码前,我们需要理解 IP 地址与域名系统(DNS)的基本关系。
IP 地址是设备在互联网上的唯一标识,类似于“数字地址”,例如 8.8.8.8 是 Google 的公共 DNS 服务器地址。而域名(如 www.example.com)则是人类更易记忆的符号化名称。
DNS 的作用类似于电话簿:当用户输入域名时,DNS 会将其解析为对应的 IP 地址,从而建立网络连接。在 Java 中,获取 IP 地址的核心逻辑正是通过 DNS 解析实现的。


方法一:使用 InetAddress 类的基础实现

Java 标准库提供了 java.net.InetAddress 类,这是获取主机 IP 地址最直接的方式。

步骤解析

  1. 创建 InetAddress 对象:通过静态方法 getByName()getLocalHost() 获取主机信息。
  2. 获取 IP 地址:调用 getHostAddress() 方法返回字符串形式的 IP 地址。

代码示例

import java.net.InetAddress;  
import java.net.UnknownHostException;  

public class HostIpFetcher {  
    public static void main(String[] args) {  
        try {  
            // 获取本地主机的 IP 地址  
            InetAddress localHost = InetAddress.getLocalHost();  
            System.out.println("本地主机 IP: " + localHost.getHostAddress());  

            // 获取指定域名的 IP 地址(例如百度)  
            InetAddress baiduHost = InetAddress.getByName("www.baidu.com");  
            System.out.println("百度 IP: " + baiduHost.getHostAddress());  
        } catch (UnknownHostException e) {  
            System.out.println("无法解析主机名或域名");  
            e.printStackTrace();  
        }  
    }  
}  

注意事项

  • 异常处理UnknownHostException 是检查异常,必须通过 try-catchthrows 处理。
  • IPv4 与 IPv6getHostAddress() 返回的可能是 IPv4 或 IPv6 地址,具体取决于 DNS 解析结果。

方法二:处理多 IP 地址的情况

某些主机可能有多个 IP 地址(如负载均衡场景),此时可通过 getAllByName() 方法获取全部地址。

代码示例

import java.net.InetAddress;  
import java.net.UnknownHostException;  

public class MultiIpFetcher {  
    public static void main(String[] args) {  
        try {  
            String hostName = "example.com";  
            InetAddress[] addresses = InetAddress.getAllByName(hostName);  
            System.out.println(hostName + " 的所有 IP 地址:");  
            for (InetAddress addr : addresses) {  
                System.out.println(addr.getHostAddress());  
            }  
        } catch (UnknownHostException e) {  
            e.printStackTrace();  
        }  
    }  
}  

对比表格

场景方法适用性
单一 IP 地址查询getByName()getLocalHost()大多数简单场景
多 IP 地址(如负载均衡)getAllByName()需要全面信息的复杂系统

进阶技巧:多线程与超时控制

在实际应用中,DNS 解析可能因网络延迟或服务器问题导致阻塞。通过设置超时时间和多线程可提升程序的健壮性。

实现思路

  1. 设置超时时间:通过 InetAddress.setUseLoopbackBackoff(boolean) 或自定义 Socket 参数控制连接超时。
  2. 多线程并发查询:针对多个主机同时查询,避免阻塞主线程。

代码示例(多线程)

import java.net.InetAddress;  
import java.net.UnknownHostException;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  

public class AsyncIpFetcher {  
    public static void main(String[] args) {  
        ExecutorService executor = Executors.newFixedThreadPool(5);  
        String[] hosts = {"google.com", "facebook.com", "twitter.com"};  

        for (String host : hosts) {  
            executor.submit(() -> {  
                try {  
                    InetAddress address = InetAddress.getByName(host);  
                    System.out.println(host + " 的 IP 是:" + address.getHostAddress());  
                } catch (UnknownHostException e) {  
                    System.out.println(host + " 解析失败");  
                }  
            });  
        }  
        executor.shutdown();  
    }  
}  

关键点解析

  • 线程池管理:通过 Executors.newFixedThreadPool() 控制并发线程数量,避免资源耗尽。
  • 异步处理:每个主机查询在独立线程中执行,互不干扰。

常见问题与解决方案

问题 1:DNS 缓存的影响

Java 的 DNS 缓存机制可能导致重复查询返回旧 IP 地址。可通过以下方式清除缓存:

// 强制刷新 DNS 缓存(需谨慎使用)  
System.clearProperty("networkaddress.cache.ttl");  

问题 2:IPv6 地址的处理

若需强制获取 IPv4 地址,可遍历所有地址并筛选:

for (InetAddress addr : addresses) {  
    if (addr instanceof java.net.Inet4Address) {  
        System.out.println("IPv4 地址:" + addr.getHostAddress());  
    }  
}  

实战案例:构建 IP 查询工具

结合上述知识点,我们可创建一个命令行工具,输入域名后返回其所有 IP 地址。

完整代码

import java.net.*;  
import java.util.Scanner;  

public class IpQueryTool {  
    public static void main(String[] args) {  
        Scanner scanner = new Scanner(System.in);  
        System.out.print("请输入要查询的域名:");  
        String input = scanner.nextLine();  

        try {  
            InetAddress[] addresses = InetAddress.getAllByName(input);  
            System.out.println(input + " 的 IP 地址如下:");  
            for (InetAddress addr : addresses) {  
                System.out.println(" - " + addr.getHostAddress());  
            }  
        } catch (UnknownHostException e) {  
            System.out.println("域名解析失败,请检查输入或网络连接。");  
        } finally {  
            scanner.close();  
        }  
    }  
}  

结论

本文通过基础到进阶的讲解,展示了 Java 中获取指定主机 IP 地址的多种方法,包括 InetAddress 类的使用、多线程优化以及常见问题的解决方案。掌握这些技能不仅能满足日常开发需求,还能为更复杂的网络编程打下坚实基础。
在实际应用中,开发者需根据场景选择合适的方法,并结合异常处理和性能优化策略,确保程序的稳定性和效率。希望本文能帮助读者深入理解这一主题,并在实践中灵活运用。

最新发布