У меня есть 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), и поэтому оно не будет иметь никаких эффектов, даже если я верну ему значение обратно в false после установки его в значение true.
Так что я могу сделать в этом случае? Это кажется общей проблемой, поэтому, безусловно, должен быть способ сделать это.
Обратите внимание, что я, конечно, могу использовать InetAddress.getByAddress()
и явно указывать IP-адрес каждой машины, чтобы получить Inet4Address
и Inet6Address
, но я не хочу этого делать, если мне действительно не нужно. Так что другие решения, пожалуйста.
О, я использую Java 1.6.0_19 на случай, если это имеет значение.
Спасибо!