Java 实例 – 获取指定主机的IP地址(超详细)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 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 地址最直接的方式。
步骤解析
- 创建
InetAddress
对象:通过静态方法getByName()
或getLocalHost()
获取主机信息。 - 获取 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-catch
或throws
处理。 - IPv4 与 IPv6:
getHostAddress()
返回的可能是 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 解析可能因网络延迟或服务器问题导致阻塞。通过设置超时时间和多线程可提升程序的健壮性。
实现思路
- 设置超时时间:通过
InetAddress.setUseLoopbackBackoff(boolean)
或自定义Socket
参数控制连接超时。 - 多线程并发查询:针对多个主机同时查询,避免阻塞主线程。
代码示例(多线程)
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
类的使用、多线程优化以及常见问题的解决方案。掌握这些技能不仅能满足日常开发需求,还能为更复杂的网络编程打下坚实基础。
在实际应用中,开发者需根据场景选择合适的方法,并结合异常处理和性能优化策略,确保程序的稳定性和效率。希望本文能帮助读者深入理解这一主题,并在实践中灵活运用。