希望同时使用 Inet4Address 和 Inet6Address 的 Java 应用程序

发布于 2024-09-26 10:38:11 字数 1395 浏览 7 评论 0原文

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

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

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

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

:出于向后兼容性的原因,默认情况下更喜欢使用 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 地址,而不是取回 Inet4AddressInet6Address,但是除非确实必要,否则我不想这样做。所以请其他解决方案。

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

谢谢!

I have a Java application that needs to connect via sockets to two different servers on two separate machines. One server has been configured to listen on IPv4 connections, while the other has been configured to listen on IPv6 connections.

Now, assuming "host1" is the machine name of the server listening on IPv4 connections, while "host2" is the machine name of the server listening on IPv6 connections. I need to get an Inet4Address for "host1" and an Inet6Address for "host2" to create a socket connection to each server, such as the following:

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

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

However, the JVM by default prefers to use IPv4 addresses over IPv6 addresses for backward compatibility reasons. So, in the above code, the first attempt to connect to "host1" succeeds, but the second attempt to connect to "host2" fails because InetAddress.getByName("host2") returns an Inet4Address instead of Inet6Address.

I understand that I can set the system property java.net.preferIPv6Addresses to true to prefer IPv6 addresses over IPv4, but this in turn causes the second attempt to connect to "host2" succeeds, but the first attempt to connect to "host1" failed(!) because InetAddress.getByName("host1") returns an Inet6Address instead of Inet4Address.

The system property java.net.preferIPv6Addresses is only being read once (see InetAddress line 212-218) and so it would have no effects even if I change its value back to false after setting it to true.

So what I can I do in this case? This seems like a common problem, so surely there has to be a way already to do it.

Note that I can of course use InetAddress.getByAddress() and supply each machine's IP address explicitly instead to get back an Inet4Address and Inet6Address, but I do not want to do this unless I really have to. So other solutions please.

Oh, I am using java 1.6.0_19 in case it matters.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

书信已泛黄 2024-10-03 10:38:11
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);
}
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);
}
π浅易 2024-10-03 10:38:11

您是否尝试过使用Inet6Address.getAllByName("host2")

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

Have you tried with Inet6Address.getAllByName("host2").

this must return IPv6 addres of host, that can be used to create socket.

怪我闹别瞎闹 2024-10-03 10:38:11

除非您对仅在 Inet6AddressInet4Address 中可用的方法有特定需求,否则不应直接使用这些类,而应使用 InetAddress

这样您就不需要进行铸造并冒获得 CCE 的风险。

就您的情况而言,我确实没有看到专门使用 IPv6 或 IPv4 类的充分理由。

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


资源:

Unless you have a specific need for methods only available in Inet6Address or Inet4Address you shouldn't use these classes directly, instead use InetAddress.

This way you won't need to cast and risk to have a CCE.

In your case I don't really see good reasons to use specifically IPv6 or IPv4 classes.

Remember, IPv6 is compatible with IPv4, so you don't really have to worry when you use an IPv4 address with an IPv6 system.


Resources :

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文