InetAddress类

1. 简介

java.net.InetAddress类是Java对Ip地址的高层表示。大多数其他网络都要用到这个类,包括Socket、ServerSocket、URL、DatagramSocket、DatagramPacket等。一般来讲,它包括一个主机名和一个IP地址。它提供了获取和操作 IP 地址的方法,可以用于网络编程、服务器配置、主机管理等场景。InetAddress类的常用方法和功能包括:

  • 获取 IP 地址:

getByName(String host):通过主机名或 IP 地址字符串获取一个 InetAddress 对象。
getLocalHost():获取本地主机的 InetAddress 对象。

  • 获取主机名和 IP 地址信息:

getHostName():获取主机的主机名。
getHostAddress():获取主机的 IP 地址字符串。

  • 检查 IP 地址类型:

isLoopbackAddress():检查是否为回环地址(Loopback Address)。
isMulticastAddress():检查是否为组播地址(Multicast Address)。
isAnyLocalAddress():检查是否为通配地址(Any Local Address)。

  • 进行 IP 地址的比较和判断:

equals(Object obj):比较两个 InetAddress 对象是否相等。
hashCode():获取 IP 地址的哈希码值。

  • 获取与 IP 地址相关的其他信息:

getCanonicalHostName():获取规范的主机名。
getAddress():获取原始的 IP 地址字节数组。
toString():返回 IP 地址的字符串表示。

InetAddress类可以用于解析域名、获取主机的 IP 地址、判断 IP 地址的类型等操作。它是进行网络编程和系统配置的基础类之一。

2. 创建新的InetAddress对象

InetAddress类没有公共构造函数。实际上,InetAddress有一些静态工厂方法,可以连接到DNS服务器来解析主机名。最常用的是InetAddress.getByName

public class QuizCardBuilder {
    public static void main(String[] args) throws  UnknownHostException {
       InetAddress address=InetAddress.getByName("www.baidu.com");
        System.out.println(address);
    }
}

在这里插入图片描述
InetAddress address=InetAddress.getByName("www.baidu.com");该方法会建立一个与本地DNS服务器的一个连接,来查找名字和数字地址(如果你之前查找过这个主机,这个信息可以在本地缓存,如果是这样,就不用建立网络连接了)。如果DNS服务器找不到这个地址,则会抛出UnknownHostException异常。

getByName方法可以提供一个IP地址作为参数,会为所请求的IP地址创建一个InetAddress对象,但不会检查DNS,即它可能会为一个实际不存在的也无法连接的主机创建InetAddress对象,而只有显示的调用getHostName时才会完成真正的DNS查找,但如果没找到的话,也不会抛出UnKnownHostException异常,而是主机名继续保持原来的IP地址字符串

  • getLocalHost()方法,会为运行这个代码的主机返回一个InetAddress对象
public class QuizCardBuilder {
    public static void main(String[] args) throws  UnknownHostException {
       InetAddress address=InetAddress.getLocalHost();
        System.out.println(address);
    }
}

在这里插入图片描述

3. 缓存

由于DNS查找的开销可能相当大,所以InetAddress会缓存查找到的结果。一旦得到一个给定主机的地址,就不会再次查找地址。只要在程序运行期间IP地址没有改变,这就没有问题。这种方式的负面结果就是,有可能刚开始尝试解析一个主机失败,但随后再次尝试时会成功。因为从远程DNS服务器发来的信息孩子传输中,第一次尝试超时,然后这个地址到达本地DNS,所以下一次请求时可用。出于这个原因,Java对于不成功的DNS查询只缓存10s。其实这个时间可以通过系统属性来控制,networkaddress.cache.ttlnetworkaddress.cache.negative.ttl。其中第一个属性指定了成功的DNS查找结果缓存的时间,单位为s,后面一个属性指定了不成功的查找结果缓存的时间,单位为s。

4. 安全性问题

从主机名创建一个新的InetAddress对象被认为是一个潜在的不安全操作,因为这需要一个DNS查找。在默认的安全管理器控制下的不可信applet(一种可以嵌入到网页中的java程序)只允许获得它的初始主机的IP地址,这可能是本地主机。不允许不可信代码(指的是那些不受信任或来源不可靠的代码。不可信代码可能是来自第三方或外部系统的代码,或者是用户输入的代码。这些代码的执行可能具有潜在的安全风险或不可预测的行为)由任何其它主机创建InetAddress对象,不可信代码可以由字符串形式的IP地址构造InetAddress对象,但不会为这样的地址完成DNS查找。由于禁止与初始主机之外的主机建立网络连接,不可信的代码不允许对第三方的主机完成任意的DNS查找,任务的DNS查找会打开一个隐藏的通道,通过它,程序可以和第三方主机对话。由于任意DNS查找会泄露信息,所以要禁止任意的DNS查找。
不可信代码允许调用getLocalHost(),不过在这种环境下,getLocalHost()总是返回主机名localhost/127.0.0.1。禁止applet找出真正的主机名和地址的原因在于,运行applet的计算机可能故意隐藏在防火墙后面,在这种情况下,applet不应该作为通道来获取web服务器还没有的信息。但与所有的安全性检查一样,禁止DNS解析可以对可信代码放宽要求,要测试一个主机能否解析可以调用checkConnect方法:

public void checkConnect(String hostname,int port)

当port参数为1时,这个方法检查能否调用DNS解析指定的hostname(如果大于-1,这个方法检查是否运行在指定端口对指定主机建立连接)

5. 获取方法

InetAddress保护4个获取方法,可以将主机名作为字符串返回,将IP地址返回为字符串和字节数组:

public String getHostname()
public String getCanonicaHostName()
public byte[] getAddress()
public String getHostAddress()

没有对应的setHostname()和setAddress()方法,这说明java.net之外的包无法在后台改变InetAddress对象的字段,所以它是线程安全的

  • getHostname

该方法返回一个String对象,其中保护主机名字,以及这个InetAddress对象表示的IP地址。如果这台机器没有主机名或者安全管理器阻止确定主机名,就会返回分四段格式的IP地址。

  • getCanonicaHostName

该方法和getHostname方法类似,不过在与DNS联系方面更加积极,getHostName只是在不知道主机名时才会联系DNS,而该方法即使知道也会联系DNS,可能会替换原来缓存的主机名。

public class QuizCardBuilder {
    public static void main(String[] args) throws  UnknownHostException {
       InetAddress address=InetAddress.getByName("www.baidu.com");
        System.out.println(address.getCanonicalHostName());
        System.out.println(address.getHostName());
    }
}

在这里插入图片描述

6. 地址类型

有些IP地址和地址模式有特殊的含义。例如127.0.0.1时本地回送地址。224.0.0.0到239.255.255.255范围内的IPv4组播地址,可以同时发送到多个订阅的主机,java提供了10个方法来测试InetAddress对象是否符合其中某个标准:

public boolean isAnyLocalAddress() //检查是不是通配地址(匹配本地的任何地址)
public boolean isLoopbackAddress() //检查是不是回送地址(回送地址直接在IP层连接一台计算机)
public boolean isLinkLocalAddress() //检查是不是iPv6本地链接地址
public boolean isSiteLocalAddress() //检查是不是一个ipv6本地网站地址
public boolean isMulticastAddress() //检查是不是一个组播地址
public boolean isMCGlocal() //检查是不是一个全球组播地址
public boolean isMCNodeLocal() //检查是不是一个本地接口组播地址
public boolean isMCSiteLocal() //检查是不是网站范围组播地址
public boolean isMCOrgLocal() //检查是不是一个组织范围组播地址
public boolean isLinkLocal() //检查是不是一个字网范围组播地址

7. 测试可达性

InetAddress类有两个isReachable方法,可以测试一个特定的节点对当前主机是否可达,连接可能因为很多原因而阻塞,包括防火墙、代理服务器、行为失常的路由器和断开线缆等,或者只是因为试图连接时远程主机没有开机

public boolean isReachable(int timeout) throw IOException
public boolean isReachable(NetworkInterface interface,int ttl, int timeout)

这些方法尝试使用traceroute(更确切的说,就是ICMP echo请求)查看指定地址是否可达,如果主机在timeout时间内没有反应,则方法返回true,否则返回false。如果网络出现错误,则抛出IOException。第二个方法还允许指定从哪个本地网络接口建立连接,以及生成时间(连接被丢弃前尝试的最大网络跳数)

public class QuizCardBuilder {
    public static void main(String[] args) {
        try {
            // 使用默认超时时间的 isReachable 方法
            boolean isReachable = InetAddress.getByName("www.baidu.com").isReachable(5000);
            System.out.println("Default Timeout - Is host reachable? " + isReachable);

            // 使用指定网络接口、生存时间和超时时间的 isReachable 方法
            NetworkInterface networkInterface = NetworkInterface.getByName("eth0");
            boolean isReachableWithInterface = InetAddress.getByName("www.baidu.com")
                    .isReachable(networkInterface, 128, 5000);
            System.out.println("With Network Interface - Is host reachable? " + isReachableWithInterface);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

8. Object方法

java.net.InetAddress继承自java.lang.Object。因此,它可以访问Object类的所有方法。

  • equals():当两个InetAddress对象具有相同的IP地址时相等,并不要求拥有相同的主机名
  • hashcode():该方法返回int只根据IP地址来计算,它不考虑主机名
  • toString():可依返回对象的简单文字表示
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值