Почему класс Java InetAddress не разрешает адреса ipv6 в их полное доменное имя?
Я пытаюсь написать простую программу с использованием Java, которая при наличии IP-адреса в формате версии 4 или 6 возвращает свое полное доменное имя. Следующий код работает нормально, если ему присвоен адрес ipv4, но вернет указанный адрес только при вводе адреса ipv6.
InetAddress inet;
try { inet = InetAddress.getByName(theIpAddress); }
catch(UnknownHostException e) { System.out.println("Unknown Host"); return; }
System.out.println(inet.getHostAddress(););
System.out.println(inet.getHostName(););
Всякий раз, когда я вхожу в ipv6, getHostName() возвращает только тот же ipv6, даже когда я знаю, что ipv6 преобразуется в полное доменное имя. Кроме того, если я введу имя хоста ipv6, например ipv6.google.com, вместо IP-адреса, произойдет исключение.
Я новичок в этом деле, поэтому буду признателен за любую помощь. Благодарю.
4 ответа
На самом деле проблема была в версии Java, на которой я работал. Обновление Java до 1.6.23, начиная с 1.6.21, позволило ipv6 разрешить их полное доменное имя.
Я провел быстрое исследование того, что происходит с разрешением имени хоста <-> ipv6 в java 8, Windows 7. Похоже, служба по умолчанию NameService вообще не работает с ipv6! Но! Java поставляется с другой реализацией NameService, основанной на JNDI, которая называется dns, sun. Итак, если вы включите его, используя либо
-Dsun.net.spi.nameservice.provider.1= DNS, вс
или же
System.setProperty("sun.net.spi.nameservice.provider.1", "dns,sun");
вы получите разрешение двунаправленного IP <-> имени хоста для адресов v4 и v6, как это
InetAddress.getAllByName(...)
address.getHostName()
Больше информации о java ipv6 вы можете найти здесь http://docs.oracle.com/javase/8/docs/technotes/guides/net/ipv6_guide/
Пытаться inet.getCanonicalHostName();
which "Получает полное доменное имя для этого IP-адреса."
Если вы создаете InetAddress, используя InetAddress.getByName()
, getHostName()
вернет то, с чем вы его построили. getCanonicalHostName()
вызывает обратный поиск имени.
С помощью java.net.InetAddress
невозможно иметь разрешение имен ipv6, ipv4 и т. д. Куча статических методов, таких как getByName
и т. д. делегировать поиск экземпляра Inet4(or 6)AddressImpl
это делает
public native InetAddress[] lookupAllHostAddr(String hostname) throws UnknownHostException;
Теперь самое интересное: а) все они являются частными / пакетными локальными, поэтому нет способа внедрить классы impl в класс InetAddress. Б) Inet4 (или 6) классы AddressImpl сами по себе являются пакетными. Таким образом, нет никакого способа сказать, сделайте ipv4 или ipv6 поиск / разрешение имен на лету. Я не понимаю, каким образом все точки расширения были заблокированы для этих классов, что делает их действительно очень ограниченным использованием и гибкостью. Здесь происходит настоящая чёрная магия, где класс InetAddress статически инициализирует impls, от чего зависит результат метода isIPv6Supported ()?? Моя установка Linux поддерживает ipv6, я могу выполнять поиск DNS для имен хостов ipv6, таких как ipv6.google.com. Буду признателен, если кто-нибудь может указать мне направление хорошей сетевой библиотеки в java для утилит ipv4/v6, таких как lookup и т. Д.
class InetAddressImplFactory {
static InetAddressImpl create() {
Object o;
if (isIPv6Supported()) {
o = InetAddress.loadImpl("Inet6AddressImpl");
} else {
o = InetAddress.loadImpl("Inet4AddressImpl");
}
return (InetAddressImpl)o;
}
static native boolean isIPv6Supported();
}