将字符串转换为 InetAddress 而不进行 DNS 查找

Posted

技术标签:

【中文标题】将字符串转换为 InetAddress 而不进行 DNS 查找【英文标题】:Convert a String to InetAddress without DNS lookup 【发布时间】:2013-12-29 10:43:32 【问题描述】:

我在String 中有一个以点分十进制表示的本地IP 地址。我想将其转换为 InetAddress 以将其提供给 Socket,但我需要在不进行 DNS 查找的情况下执行此操作(因为这可能会导致长时间超时)。

是否有现成的方法,或者我需要拆分String 并从其字节中创建InetAddress

更新工厂方法InetAddress.getByName()InetAddress.getByAddress() 似乎不太合适,因为它们都接受诸如java.sun.com 之类的主机名。没有人说他们是否会在实施过程中尝试联系 DNS 服务器。

【问题讨论】:

Is there an easy way to convert String to Inetaddress in Java? 的可能重复项 @Zelldon,同意。不过,我不想将整个库仅用于这些功能。 ***.com/questions/5571744/… 也是同样的问题 @Zelldon 是的,但答案不同。我想 100% 确定没有网络活动正在进行。 【参考方案1】:

这样做

InetAddress inetAddress = InetAddress.getByName("192.168.0.105");

如果提供了文字 IP 地址,则只有地址的有效性 检查格式。

java源码

// if host is an IP address, we won't do further lookup    
if (Character.digit(host.charAt(0), 16) != -1 || (host.charAt(0) == ':')) 


【讨论】:

是否保证不会发生 DNS(也没有反向 DNS 或其他)? @BartFriederichs 根据 java 文档,如果提供了正确的 ip 格式,则没有 DNS 验证。参考 - docs.oracle.com/javase/7/docs/api/java/net/… 源码也是这么说的:'如果host是IP地址,我们就不会再查找了' 如果提供的字符串是点分四边形格式,它不会进行 dns 查找。如果您需要确定,请先验证字符串,例如. ***.com/questions/5667371/validate-ip-address 就我而言,InetAddress address= InetAddress.getByName("www.sun.com");运行正确,但是当我给出错误的主机地址作为参数时,例如“www.sunqqq.com”,它给出了异常。 >>> java.net.UnknownHostException: www.sunqqq.com at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) at java.net.InetAddress$1.lookupAllHostAddr(Unknown Source) at java.net.InetAddress.getAddressesFromNameService(Unknown Source ) 在 java.net.InetAddress.getAllByName0(Unknown Source) at java.net.InetAddress.getAllByName(Unknown Source)....(更多)【参考方案2】:

您可以使用专门针对您的用例记录的Guava's InetAddresses#forString()

返回具有给定字符串表示的InetAddress这故意避免了所有名称服务查找(例如,没有 DNS)。

(强调)

【讨论】:

【参考方案3】:

您可以使用 getByName 方法来做到这一点。例如:

InetAddress localhost = InetAddress.getByName("127.0.0.1")

正如 java 文档中描述的那样:

主机名可以是机器名称,例如“java.sun.com”,也可以是其 IP 地址的文本表示。如果提供的是文字 IP 地址,则只检查地址格式的有效性。

【讨论】:

就我而言,InetAddress address= InetAddress.getByName("www.sun.com");运行正确,但是当我给出错误的主机地址作为参数时,例如“www.sunqqq.com”,它给出了异常。 >>> java.net.UnknownHostException: www.sunqqq.com at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) at java.net.InetAddress$1.lookupAllHostAddr(Unknown Source) at java.net.InetAddress.getAddressesFromNameService(Unknown Source ) 在 java.net.InetAddress.getAllByName0(Unknown Source) at java.net.InetAddress.getAllByName(Unknown Source)....(更多) – 这是否意味着 getByName() 方法进行 DNS 检查?好像主机地址的有效性也检查过了??? 是的。如果你给 getByName 一个主机名,它会执行 DNS 查找。但如果提供了 IP 地址,它只会检查 IP 的有效性(字符串格式)。【参考方案4】:

The open-source IPAddress Java library 将验证 IPv6 和 IPv4 的所有标准表示,并且不会进行 DNS 查找。免责声明:我是该库的项目经理。

以下代码将满足您的要求:

        String str = "fe80:0:0:0:f06c:31b8:cd17:5a44";
        try 
            IPAddressString str = new IPAddressString(str);
            IPAddress addr = str.toAddress();//throws if invalid, without a DNS lookup
            InetAddress inetAddr = addr.toInetAddress();//convert valid address
            //use address
         catch(AddressStringException e) 
            //e.getMessage has validation error
        

【讨论】:

以上是关于将字符串转换为 InetAddress 而不进行 DNS 查找的主要内容,如果未能解决你的问题,请参考以下文章

将xml转换为json而不转换字符串/整数?

从Int获取单个数字而不使用字符串?

打印 DataGridView 而不将其转换为位图

将十进制字符串转换为十六进制字符串而不将字符串转换为整数

mysql c api:插入数字而不将它们转换为字符串

将随机整数转换为范围 [min,max] 而不进行分支