【问题标题】:Why Inet6Address.getByAddress requires both hostname AND direct address bytes?为什么 Inet6Address.getByAddress 需要主机名和直接地址字节?
【发布时间】:2019-10-11 04:48:20
【问题描述】:

https://docs.oracle.com/javase/7/docs/api/java/net/Inet6Address.html

public static Inet6Address getByAddress(String host,
                        byte[] addr,
                        int scope_id)

Inet6Address 应该包含类似sockaddr_in6 的无端口号(16 个地址字节加上本地链接的 scope_id),至少我是这么认为的。给定 16 个字节和范围 id,我想应该完全指定 Inet6Address,而不需要更多位。然而还有额外的论点host...

说明InetAddr.getByAddress(String,byte[])的文档链接,其中还包含不清楚的sn-p:

根据提供的主机名和 IP 地址创建 InetAddress。不检查名称服务的地址有效性。
主机名可以是机器名,例如“java.sun.com”,也可以是其 IP 地址的文本表示形式。

也不对主机名进行有效性检查。

如果没有 DNS,那么为什么在已经提供字节的情况下还需要主机名?它可以与null 一起使用而不是主机吗?为什么没有getByAddress,只有addrscope_id(没有host)?

【问题讨论】:

    标签: java networking


    【解决方案1】:

    首先,有一个工厂方法只接受字节数组并执行您所期望的操作:

    byte[] addr = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
    InetAddress ip = Inet6Address.getByAddress(addr);
    

    但是,我们对主机名部分感兴趣,所以让我们阅读documentation 中的getHostName()

    获取此 IP 地址的主机名。

    如果此 InetAddress 是使用主机名创建的,则此主机名将 被记住并返回;否则,反向名称查找将是 执行并根据系统配置返回结果 名称查找服务。

    我们已经构建了第一个没有主机名的 IP 地址,因此根据 javadoc,调用 getHostName() 将执行实际查找。这可能不是我们想要的,也可能不是我们想要的,所以 java 给了我们第二个选择。如果我们这样构建地址:

    InetAddress ip = InetAddress.getByAddress("foo", addr);
    

    然后getHostName() 将简单地打印 我们 提供的主机名 (foo) 而无需任何查找。

    顺便说一句,同样的解释可以在javadoc 中找到InetAddress 本身:

    InetAddress 的实例包含一个 IP 地址并且可能 其对应的主机名(取决于是否构造 带有主机名或是否已经完成反向主机名 分辨率)。

    【讨论】:

    • “有一个工厂方法只接受字节数组并做你所期望的” -> 是否有相应的方法接受字节数组和范围ID?
    • @Vi。有点。通过传递null 的主机名,您将获得相同的效果。这不是很好,因为这种行为在任何地方都没有记录,所以它可能会在 Java 版本甚至 JDK 实现之间发生变化。尽管如此,这是我所知道的唯一等效的 API。我完全同意这是一个奇怪的 API 选择。
    猜你喜欢
    • 2014-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-18
    • 2015-09-22
    • 2018-06-10
    • 2022-06-11
    相关资源
    最近更新 更多