6

我有一个 Java 应用程序需要通过套接字连接到两台不同机器上的两台不同服务器。一台服务器已配置为侦听 IPv4 连接,而另一台服务器已配置为侦听 IPv6 连接。

现在,假设“host1”是侦听 IPv4 连接的服务器的机器名,而“host2”是侦听 IPv6 连接的服务器的机器名。我需要Inet4Address为“host1”和Inet6Address“host2”创建一个到每个服务器的套接字连接,如下所示:

Inet4Address inet4 = (Inet4Address)InetAddress.getByName("host1");
InetSocketAddress soc4 = new InetSocketAddress(inet4, 7777);
...

Inet6Address inet6 = (Inet6Address)InetAddress.getByName("host2");
InetSocketAddress soc6 = new InetSocketAddress(inet6, 7777);
...

但是,出于向后兼容性的原因,JVM 默认更喜欢使用 IPv4 地址而不是 IPv6 地址。因此,在上面的代码中,第一次尝试连接到“host1”成功,但第二次尝试连接到“host2”失败,因为InetAddress.getByName("host2")返回的是一个Inet4Address而不是Inet6Address.

我知道我可以将系统属性设置java.net.preferIPv6Addresses为 true 以更喜欢 IPv6 地址而不是 IPv4,但这反过来会导致第二次尝试连接到“host2”成功,但第一次尝试连接到“host1”失败(!)因为InetAddress.getByName("host1")返回一个Inet6Address而不是Inet4Address

系统属性java.net.preferIPv6Addresses只被读取一次(参见 InetAddress 行 212-218),因此即使我在将其设置为 true 后将其值更改回 false,它也不会产生任何影响。

那么在这种情况下我能做些什么呢?这似乎是一个普遍的问题,所以肯定已经有一种方法可以做到这一点。

请注意,我当然可以InetAddress.getByAddress()显式使用和提供每台机器的 IP 地址来取回Inet4Addressand Inet6Address,但我不想这样做,除非我真的必须这样做。所以请其他解决方案。

哦,我正在使用 java 1.6.0_19 以防万一。

谢谢!

4

3 回答 3

6
static Inet6Address getInet6AddressByName(String host) throws UnknownHostException, SecurityException
{
    for(InetAddress addr : InetAddress.getAllByName(host))
    {
        if(addr instanceof Inet6Address)
            return (Inet6Address)addr;
    }
    throw new UnknownHostException("No IPv6 address found for " + host);
}
于 2010-10-06T12:03:33.190 回答
0

你试过用Inet6Address.getAllByName("host2").

这必须返回主机的 IPv6 地址,可用于创建套接字。

于 2010-10-06T06:44:19.007 回答
-1

除非您对仅在其中可用的方法有特殊需求,Inet6Address或者Inet4Address您不应该直接使用这些类,否则请使用InetAddress.

这样,您就无需进行投射和冒险获得 CCE。

在您的情况下,我真的看不出专门使用 IPv6 或 IPv4 类的充分理由。

请记住,IPv6 与 IPv4 兼容,因此当您在 IPv6 系统中使用 IPv4 地址时,您不必担心。


资源 :

于 2010-10-04T09:20:18.920 回答