Mam aplikację Java, która musi łączyć się przez gniazda do dwóch różnych serwerów na dwóch oddzielnych komputerach. Jeden serwer został skonfigurowany do nasłuchu na połączeniach IPv4, podczas gdy drugi został skonfigurowany do nasłuchu na połączeniach IPv6.Aplikacja Java, która chce używać zarówno Inet4Address, jak i Inet6Address w tym samym czasie.
Zakładając, że "host1" to nazwa urządzenia serwera nasłuchującego na połączeniach IPv4, a "host2" to nazwa urządzenia serwera nasłuchującego na połączeniach IPv6. Muszę dostać Inet4Address
dla „host1” i Inet6Address
dla „host2”, aby utworzyć połączenie z gniazdem do każdego serwera, takich jak:
Inet4Address inet4 = (Inet4Address)InetAddress.getByName("host1");
InetSocketAddress soc4 = new InetSocketAddress(inet4, 7777);
...
Inet6Address inet6 = (Inet6Address)InetAddress.getByName("host2");
InetSocketAddress soc6 = new InetSocketAddress(inet6, 7777);
...
jednak JVM domyślnie woli używać adresów IPv4 na Adresy IPv6 ze względu na kompatybilność wsteczną. Tak więc, w powyższym kodzie pierwsza próba połączenia z "host1" się powiedzie, ale druga próba połączenia z "host2" nie powiedzie się, ponieważ InetAddress.getByName("host2")
zwraca Inet4Address
zamiast Inet6Address
.
Rozumiem, że mogę ustawić właściwość systemu na true, aby preferować adresy IPv6 przez IPv4, ale to z kolei powoduje, że druga próba połączenia z "host2" się powiedzie, ale pierwsza próba połączenia z "host1" nie powiodła się (!) ponieważ InetAddress.getByName("host1")
zwraca wartość Inet6Address
zamiast Inet4Address
.
Właściwość systemowa jest tylko odczytywana tylko raz (patrz wiersz InetAddress 212-218), więc nie będzie miała żadnych efektów, nawet jeśli zmienię jej wartość na wartość false po ustawieniu na wartość true.
Co mogę zrobić w tym przypadku? Wydaje się, że jest to powszechny problem, więc na pewno musi istnieć sposób, aby to zrobić.
Zauważ, że mogę oczywiście użyć i podać adres IP każdego komputera jawnie zamiast tego, aby otrzymać ponownie Inet4Address
i Inet6Address
, ale nie chcę tego robić, chyba że naprawdę muszę. Więc proszę o inne rozwiązania.
Och, używam języka Java 1.6.0_19 na wszelki wypadek.
Dzięki!
Ja. Jak już powiedziałem, dwa serwery nasłuchują odpowiednio połączeń IPv4 i IPv6. Oddanie, które zrobiłem w powyższym przykładowym kodzie, miało pokazać, że chciałem (i muszę) uzyskać 'Inet6Address', który następnie muszę przekazać do' InetSocketAddress', aby połączyć się z "host2" (przekazanie 'Inet4Address' spowoduje spowodować błąd połączenia). Tak więc, mimo że używam tylko nadklasy 'InetAddress' przez cały czas, pod spodem jest to albo' Inet4Address' albo 'Inet6Address', czyż nie? I w tym przypadku chciałem, aby oczywiste było, że mam problem, wykonując casting jawnie. – His
Tak, nadal będzie to tylko 'Inet4Address' lub' Inet6Address' i jaki będzie to problem? IPv6 jest kompatybilny z IPv4, więc nie powinno być problemu. –
Cóż, nie jestem pewien, ponieważ tego nie doświadczyłem. Nie mogę użyć 'Inet6Address' (lub' InetAddress', jeśli chcesz) do połączenia się z serwerem nasłuchującym na połączeniu IPv4 - dostaję błąd połączenia. To: 'new InetSocketAddress (InetAddress.getByName (" host1 "), 7777)' z 'InetAddress.getByName (" host1 ")' zwracając adres Inet6Address/InetAddress, nie będzie działać. Ale jeśli 'InetAddress.getByName (" host1 ")' zwraca 'Inet4Address/InetAddress', to by działało. – His