ソケットを介して 2 つの別々のマシン上の 2 つの異なるサーバーに接続する必要がある Java アプリケーションがあります。一方のサーバーは IPv4 接続をリッスンするように構成され、もう一方のサーバーは IPv6 接続をリッスンするように構成されています。
ここで、「host1」は IPv4 接続をリッスンするサーバーのマシン名であり、「host2」は IPv6 接続をリッスンするサーバーのマシン名であるとします。次のように、各サーバーへのソケット接続を作成するにはInet4Address
、「host1」用と「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);
...
ただし、JVM はデフォルトで、後方互換性の理由から、IPv6 アドレスよりも IPv4 アドレスを使用することを優先します。したがって、上記のコードでは、「host1」への最初の接続試行は成功しますが、「host2」への 2 回目の接続試行は失敗しInetAddress.getByName("host2")
ます。Inet4Address
Inet6Address
IPv4 よりも IPv6 アドレスを優先するようにシステム プロパティを true に設定できることは理解していjava.net.preferIPv6Addresses
ますが、これにより、「host2」への 2 回目の接続試行は成功しますが、「host1」への最初の接続試行は失敗しInetAddress.getByName("host1")
ます(!)。のInet6Address
代わりにInet4Address
。
システム プロパティjava.net.preferIPv6Addresses
は 1 回だけ読み取られるため (InetAddress の 212 ~ 218 行を参照)、値を true に設定した後に値を false に戻しても効果はありません。
では、この場合どうすればよいのでしょうか。これはよくある問題のように思えるので、すでにそれを行う方法があるに違いありません。
InetAddress.getByAddress()
もちろん、代わりに各マシンの IP アドレスを明示的に使用および提供して、 Inet4Address
andを取得するInet6Address
こともできますが、本当に必要でない限り、これを実行したくありません。他の解決策をお願いします。
ああ、問題が発生した場合に備えて、Java 1.6.0_19 を使用しています。
ありがとう!