Java-Anwendung nutzen wollen, die beide Inet4Address und Inet6Address zur gleichen Zeit
Ich habe eine Java-Anwendung, um eine Verbindung über sockets bis zu zwei Server auf zwei getrennten Maschinen. Ein server so konfiguriert wurde, hören Sie auf IPv4-verbindungen, während die anderen, die so konfiguriert wurde, zu hören auf IPv6-verbindungen.
Nun, davon ausgehend, "host1" ist der Computername des server lauscht auf IPv4-verbindungen, während "host2" ist der Computername des server listening on IPv6-verbindungen. Ich brauche, um eine Inet4Address
für "host1" und ein Inet6Address
für "host2" zum erstellen einer socket-Verbindung zu jedem server, wie den folgenden:
Inet4Address inet4 = (Inet4Address)InetAddress.getByName("host1");
InetSocketAddress soc4 = new InetSocketAddress(inet4, 7777);
...
Inet6Address inet6 = (Inet6Address)InetAddress.getByName("host2");
InetSocketAddress soc6 = new InetSocketAddress(inet6, 7777);
...
Jedoch die JVM standardmäßig bevorzugt IPv4-Adressen auf IPv6-Adressen aus Gründen der Abwärtskompatibilität. Also, der obige code, der erste Versuch, eine Verbindung zu "host1" gelingt, aber der zweite Versuch, eine Verbindung zu "host2" schlägt fehl, weil InetAddress.getByName("host2")
gibt ein Inet4Address
statt Inet6Address
.
Ich verstehe, dass ich kann die system-property java.net.preferIPv6Addresses
um wahr zu bevorzugen IPv6-Adressen gegenüber IPv4, aber dies wiederum bewirkt, dass der zweite Versuch eine Verbindung zu "host2" gelingt, aber der erste Versuch, eine Verbindung zu "host1" ist fehlgeschlagen(!) da InetAddress.getByName("host1")
gibt ein Inet6Address
statt Inet4Address
.
Dem system property java.net.preferIPv6Addresses
ist nur einmal gelesen (siehe InetAddress-line 212-218) und so hätte es keine Auswirkungen, auch wenn ich ändern Sie den Wert zurück auf false, nachdem Sie es auf true.
Also, was kann ich tun in diesem Fall? Dies scheint ein häufiges problem, so gibt es sicherlich einen Weg geben, schon um es zu tun.
Beachten Sie, dass kann ich natürlich InetAddress.getByAddress()
und liefern jede Maschine mit der IP-Adresse explizit statt, um wieder ein Inet4Address
und Inet6Address
, aber ich will nicht, dies zu tun, es sei denn, ich habe wirklich zu. Also andere Lösungen bitte.
Oh, ich bin mit java 1.6.0_19 in Fall ist es wichtig.
Dank!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es sei denn, Sie haben eine spezifische Notwendigkeit für Methoden, die nur in
Inet6Address
oderInet4Address
sollten Sie nicht verwenden diese Klassen direkt, sondern verwenden SieInetAddress
.Diese Weise brauchen Sie nicht zu werfen und Gefahr zu haben, der ein CCE.
In Ihrem Fall sehe ich nicht wirklich gute Gründe für die Verwendung von speziell IPv6-oder IPv4-Klassen.
Denken Sie daran, IPv6 ist kompatibel mit IPv4, so dass Sie nicht wirklich sorgen zu machen, wenn du eine IPv4 Adresse mit einer IPv6-system.
Ressourcen :
Inet6Address
die ich dann übergeben müssen, umInetSocketAddress
eine Verbindung zu "host2" (übergabe einerInet4Address
verursachen einen Ausfall der Verbindung). So, obwohl ich gerade das OberklasseInetAddress
alle die Zeit, darunter ist es eigentlich entwederInet4Address
oderInet6Address
, ist es nicht? Und in diesem Fall wollte ich klar machen das problem ich habe, indem Sie die Typumwandlung explizit.Inet4Address
oder nurInet6Address
, und was ist das problem mit ihm? IPv6 ist kompatibel mit IPv4 sollte es kein problem sein.Inet6Address
(oderInetAddress
wenn Sie möchten), um eine Verbindung zu dem server lauscht auf IPv4-Verbindung - ich bekomme einen Verbindungsfehler. Diese:new InetSocketAddress(InetAddress.getByName("host1"), 7777)
mitInetAddress.getByName("host1")
Rückkehr Inet6Address/InetAddress, wird nicht funktionieren. Aber wennInetAddress.getByName("host1")
gibt einInet4Address/InetAddress
es funktionieren würde.Haben Sie versucht, mit
Inet6Address.getAllByName("host2")
.diese zurückgeben müssen IPv6-Adresse des host, der verwendet werden kann zum erstellen von socket.
Inet6Address
nicht eine bestimmte Implementierung dergetAllByName(String)
, so ruftInet6Address.getAllByName(String)
ist wirklich das gleiche wie der Aufruf der parent-statische MethodeInetAddress.getAllByName(String)
.