Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java application wanting to use both Inet4Address and Inet6Address at the same time

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!

like image 935
His Avatar asked Oct 04 '10 07:10

His


People also ask

What is the difference between inet4address and inet6address?

Inet4Address and Inet6Address represent IPv4 and IPv6 addresses, respectively. However, when writing network applications, you don’t have to concern about IPv4 or IPv6 as Java hides all the details. The InetAddress can refer to either Inet4Address or Inet6Address so most of the time, using InetAddress is enough.

What is inet6address class in Java?

Java.net.Inet6Address class in Java. This class represents IPv6 address and extends the InetAddress class. Methods of this class provide facility to represent and interpret IPv6 addresses. Methods of this class takes input in the following formats:

What is inetaddress in Java network API?

This article helps you understand InetAddress - a fundamental class in Java Network API. The InetAddress class represents an IP address, both IPv4 and IPv6. Basically you create instances of this class to use with other classes such as Socket, ServerSocket, DatagramPacket and DatagramSocket.

How to create an inet6address object in IPv6?

getByAddress (String host, byte [] addr, int scope_id) : This is used to create an Inet6Address object by setting a IPv6 scope id to the given value. Object returned is similar to as created by InetAddress.getByAddress (String, byte []) with additional info about scope id.


1 Answers

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);
}
like image 189
Andrew Duffy Avatar answered Sep 28 '22 09:09

Andrew Duffy