Assume an IPv4 TCP server is running on a dual stack host (i.e., one that supports both IPv4 and IPv6). Now, on a machine that is also dual stack, doing
new Socket(InetAddress.getByName(host), port)
where host is a machine name (not a literal IPv4 or IPv6 address), results in a ConnectExceptin ("Connection refused"). The reason is that InetAddress.getByName(host) seems to prefer an IPv6 address over an IPv4 address for the given host.
A solution would be to have another API that defers name resolution until the actual connect(2) call is made, then trying all addresses returned by getaddrinfo(3) until one succeeds (see Stevens, Fenner, Rudoff: "Unix Network Programming, Volume 1: The Sockets Networking API, 3rd Edition", p. 359). (I tried
new Socket().connect(InetSocketAddress.createUnresolved(host, port))
hoping that this might do the delayed resolution, but instead it results in an UnknownHostException.)
The scenario where I encountered this problem is as follows: StarOffice/OpenOffice is running as a server (it only supports IPv4) and you try to connect a Java client on the same machine via OpenOffice's remote UNO protocol, and the Java client uses the machine name "localhost" for the connection. On the given machine, "localhost" can resolve to both IPv6 ::1 and IPv4 127.0.0.1 (and Java chooses the IPv6 address). A workaround is to explicitly use "127.0.0.1" instead of "localhost" in the client. (See <http://www.openoffice.org/issues/show_bug.cgi?id=32281>.)