跳转到内容

Java InetAddress类

来自代码酷


Java InetAddress类是Java网络编程中用于表示IP地址(包括IPv4和IPv6)的核心类,位于java.net包中。它提供了主机名解析、IP地址封装和网络地址操作的功能,是构建网络应用程序的基础组件之一。

概述[编辑 | 编辑源代码]

InetAddress类是一个不可变对象,表示一个网络协议(IP)地址。它不包含公开的构造方法,而是通过静态工厂方法创建实例。主要功能包括:

  • 封装IPv4或IPv6地址
  • 提供主机名解析(正向/反向DNS查询)
  • 支持本地地址检测(如回环地址127.0.0.1)

核心方法[编辑 | 编辑源代码]

以下是InetAddress类的主要静态方法:

方法 描述
getByName(String host) 通过主机名获取InetAddress对象
getAllByName(String host) 获取主机名对应的所有IP地址(数组)
getLocalHost() 获取本地主机的InetAddress对象
getLoopbackAddress() 获取回环地址(127.0.0.1或::1)

实例方法包括:

方法 描述
getHostAddress() 返回IP地址字符串
getHostName() 返回主机名
isReachable(int timeout) 测试地址是否可达

代码示例[编辑 | 编辑源代码]

基础用法[编辑 | 编辑源代码]

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

public class InetAddressDemo {
    public static void main(String[] args) {
        try {
            // 获取本地主机地址
            InetAddress localHost = InetAddress.getLocalHost();
            System.out.println("Local Host: " + localHost);
            
            // 通过主机名获取地址
            InetAddress googleAddress = InetAddress.getByName("www.google.com");
            System.out.println("Google IP: " + googleAddress.getHostAddress());
            
            // 检查回环地址
            InetAddress loopback = InetAddress.getLoopbackAddress();
            System.out.println("Is loopback: " + loopback.isLoopbackAddress());
            
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

示例输出:

Local Host: MyComputer.local/192.168.1.100
Google IP: 172.217.168.36
Is loopback: true

多地址解析[编辑 | 编辑源代码]

// 获取一个域名的所有IP地址
InetAddress[] allAddresses = InetAddress.getAllByName("www.github.com");
for (InetAddress addr : allAddresses) {
    System.out.println("GitHub Server: " + addr.getHostAddress());
}

网络可达性检测[编辑 | 编辑源代码]

InetAddress提供了测试网络连接的方法:

InetAddress address = InetAddress.getByName("192.168.1.1");
if (address.isReachable(5000)) { // 5秒超时
    System.out.println("Host is reachable");
} else {
    System.out.println("Host NOT reachable");
}

IPv4与IPv6支持[编辑 | 编辑源代码]

Java通过InetAddress的派生类支持不同IP版本:

  • Inet4Address - IPv4地址
  • Inet6Address - IPv6地址

可以通过instanceof检查地址类型:

InetAddress addr = InetAddress.getByName("2001:db8::1");
if (addr instanceof Inet6Address) {
    System.out.println("This is an IPv6 address");
}

实际应用案例[编辑 | 编辑源代码]

网络扫描工具[编辑 | 编辑源代码]

以下代码片段展示了如何用InetAddress构建简单的本地网络扫描器:

public class NetworkScanner {
    public static void scanLocalNetwork(String baseIP, int timeout) {
        for (int i = 1; i < 255; i++) {
            String ip = baseIP + i;
            try {
                InetAddress address = InetAddress.getByName(ip);
                if (address.isReachable(timeout)) {
                    System.out.println(ip + " is alive. Hostname: " 
                        + address.getHostName());
                }
            } catch (Exception e) {
                // 忽略不可达的主机
            }
        }
    }
    
    public static void main(String[] args) {
        scanLocalNetwork("192.168.1.", 200);
    }
}

反向DNS查询[编辑 | 编辑源代码]

InetAddress addr = InetAddress.getByName("8.8.8.8");
System.out.println("Host name for 8.8.8.8: " + addr.getHostName());

性能考虑[编辑 | 编辑源代码]

  • DNS查询是阻塞操作,在生产环境中应考虑使用缓存或异步API
  • isReachable()方法的实现依赖于ICMP协议,可能被防火墙阻止
  • 频繁的主机名解析应考虑使用InetAddress.getByAddress()避免DNS查询

安全注意事项[编辑 | 编辑源代码]

  • 主机名解析可能受到DNS欺骗攻击影响
  • 不可信的IP地址输入应进行验证
  • 敏感操作前应验证isLoopbackAddress()isAnyLocalAddress()

常见问题[编辑 | 编辑源代码]

为什么getHostName()有时返回IP地址?[编辑 | 编辑源代码]

当无法完成反向DNS查询时,该方法会返回IP地址字符串而非主机名。

如何处理UnknownHostException?[编辑 | 编辑源代码]

此异常表示主机名无法解析为IP地址,应捕获并处理:

try {
    InetAddress.getByName("unknown.host");
} catch (UnknownHostException e) {
    System.err.println("无法解析主机名");
    // 使用默认地址或提示用户
}

进阶主题[编辑 | 编辑源代码]

地址类型检测[编辑 | 编辑源代码]

InetAddress提供了多种地址类型检测方法:

  • isMulticastAddress() - 检测多播地址(224.0.0.0/4)
  • isLinkLocalAddress() - 检测链路本地地址(169.254.0.0/16)
  • isSiteLocalAddress() - 检测站点本地地址(私有IP范围)

网络接口绑定[编辑 | 编辑源代码]

通过NetworkInterface类可以获取绑定到特定接口的InetAddress:

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
    NetworkInterface ni = interfaces.nextElement();
    Enumeration<InetAddress> addresses = ni.getInetAddresses();
    while (addresses.hasMoreElements()) {
        InetAddress addr = addresses.nextElement();
        System.out.println(ni.getName() + ": " + addr);
    }
}

总结[编辑 | 编辑源代码]

InetAddress类是Java网络编程的基础组件,提供了:

  • IP地址的抽象表示
  • 主机名解析功能
  • 网络可达性测试
  • IP版本透明处理

掌握InetAddress的使用是开发网络感知应用程序的重要第一步。在实际应用中,应结合具体需求选择合适的方法,并注意异常处理和性能优化。

graph TD A[创建InetAddress] --> B[通过主机名] A --> C[通过IP字符串] A --> D[获取本地地址] B --> E[DNS查询] C --> F[直接解析] D --> G[系统网络配置] E --> H[返回IP地址] F --> H G --> H H --> I[地址操作] I --> J[获取主机名] I --> K[测试可达性] I --> L[地址类型检测]