📄 inetaddress.java
字号:
return new Inet4Address(host, addr); } else if (addr.length == Inet6Address.INADDRSZ) { byte[] newAddr = Inet6Address.convertFromIPv4MappedAddress(addr); if (newAddr != null) { return new Inet4Address(host, newAddr); } else { return new Inet6Address(host, addr); } } } throw new UnknownHostException("addr is of illegal length"); } /** * Determines the IP address of a host, given the host's name. * * <p> The host name can either be a machine name, such as * "<code>java.sun.com</code>", or a textual representation of its * IP address. If a literal IP address is supplied, only the * validity of the address format is checked. * * <p> For <code>host</code> specified in literal IPv6 address, * either the form defined in RFC 2732 or the literal IPv6 address * format defined in RFC 2373 is accepted. * * <p> If the host is <tt>null</tt> then an <tt>InetAddress</tt> * representing an address of the loopback interface is returned. * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a> * section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a> * section 2.5.3. </p> * * @param host the specified host, or <code>null</code>. * @return an IP address for the given host name. * @exception UnknownHostException if no IP address for the * <code>host</code> could be found. * @exception SecurityException if a security manager exists * and its checkConnect method doesn't allow the operation */ public static InetAddress getByName(String host) throws UnknownHostException { return InetAddress.getAllByName(host)[0]; } /** * Given the name of a host, returns an array of its IP addresses, * based on the configured name service on the system. * * <p> The host name can either be a machine name, such as * "<code>java.sun.com</code>", or a textual representation of its IP * address. If a literal IP address is supplied, only the * validity of the address format is checked. * * <p> For <code>host</code> specified in literal IPv6 address, * either the form defined in RFC 2732 or the literal IPv6 address * format defined in RFC 2373 is accepted. * * <p> If the host is <tt>null</tt> then an <tt>InetAddress</tt> * representing an address of the loopback interface is returned. * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC 3330</a> * section 2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a> * section 2.5.3. </p> * * <p> If there is a security manager and <code>host</code> is not * null and <code>host.length() </code> is not equal to zero, the * security manager's * <code>checkConnect</code> method is called * with the hostname and <code>-1</code> * as its arguments to see if the operation is allowed. * * @param host the name of the host, or <code>null</code>. * @return an array of all the IP addresses for a given host name. * * @exception UnknownHostException if no IP address for the * <code>host</code> could be found. * @exception SecurityException if a security manager exists and its * <code>checkConnect</code> method doesn't allow the operation. * * @see SecurityManager#checkConnect */ public static InetAddress[] getAllByName(String host) throws UnknownHostException { if (host == null || host.length() == 0) { InetAddress[] ret = new InetAddress[1]; ret[0] = impl.loopbackAddress(); return ret; } boolean ipv6Expected = false; if (host.charAt(0) == '[') { // This is supposed to be an IPv6 litteral if (host.length() > 2 && host.charAt(host.length()-1) == ']') { host = host.substring(1, host.length() -1); ipv6Expected = true; } else { // This was supposed to be a IPv6 address, but it's not! throw new UnknownHostException(host); } } // if host is an IP address, we won't do further lookup if (Character.digit(host.charAt(0), 16) != -1 || (host.charAt(0) == ':')) { byte[] addr = null; // see if it is IPv4 address addr = Inet4Address.textToNumericFormat(host); if (addr == null) { // see if it is IPv6 address addr = Inet6Address.textToNumericFormat(host); } else if (ipv6Expected) { // Means an IPv4 litteral between brackets! throw new UnknownHostException("["+host+"]"); } InetAddress[] ret = new InetAddress[1]; if(addr != null) { if (addr.length == Inet4Address.INADDRSZ) { ret[0] = new Inet4Address(null, addr); } else { ret[0] = new Inet6Address(null, addr); } return ret; } } else if (ipv6Expected) { // We were expecting an IPv6 Litteral, but got something else throw new UnknownHostException("["+host+"]"); } return getAllByName0(host); } private static InetAddress[] getAllByName0 (String host) throws UnknownHostException { return getAllByName0(host, true); } /** * package private so SocketPermission can call it */ static InetAddress[] getAllByName0 (String host, boolean check) throws UnknownHostException { /* If it gets here it is presumed to be a hostname */ /* Cache.get can return: null, unknownAddress, or InetAddress[] */ Object obj = null; Object objcopy = null; /* make sure the connection to the host is allowed, before we * give out a hostname */ if (check) { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkConnect(host, -1); } } obj = getCachedAddress(host); /* If no entry in cache, then do the host lookup */ if (obj == null) { try { obj = getAddressFromNameService(host); } catch (UnknownHostException uhe) { throw new UnknownHostException(host + ": " + uhe.getMessage()); } } if (obj == unknown_array) throw new UnknownHostException(host); /* Make a copy of the InetAddress array */ objcopy = ((InetAddress [])obj).clone(); return (InetAddress [])objcopy; } private static Object getAddressFromNameService(String host) throws UnknownHostException { Object obj = null; boolean success = false; // Check whether the host is in the lookupTable. // 1) If the host isn't in the lookupTable when // checkLookupTable() is called, checkLookupTable() // would add the host in the lookupTable and // return null. So we will do the lookup. // 2) If the host is in the lookupTable when // checkLookupTable() is called, the current thread // would be blocked until the host is removed // from the lookupTable. Then this thread // should try to look up the addressCache. // i) if it found the address in the // addressCache, checkLookupTable() would // return the address. // ii) if it didn't find the address in the // addressCache for any reason, // it should add the host in the // lookupTable and return null so the // following code would do a lookup itself. if ((obj = checkLookupTable(host)) == null) { // This is the first thread which looks up the address // this host or the cache entry for this host has been // expired so this thread should do the lookup. try { /* * Do not put the call to lookup() inside the * constructor. if you do you will still be * allocating space when the lookup fails. */ byte[][] byte_array; byte_array = nameService.lookupAllHostAddr(host); InetAddress[] addr_array = new InetAddress[byte_array.length]; for (int i = 0; i < byte_array.length; i++) { byte addr[] = byte_array[i]; if (addr.length == Inet4Address.INADDRSZ) { addr_array[i] = new Inet4Address(host, addr); } else { addr_array[i] = new Inet6Address(host, addr); } } obj = addr_array; success = true; } catch (UnknownHostException uhe) { obj = unknown_array; success = false; throw uhe; } finally { try { // Cache the address. cacheAddress(host, obj, success); } finally { // Delete the host from the lookupTable, and // notify all threads waiting for the monitor // for lookupTable. updateLookupTable(host); } } } return obj; } private static Object checkLookupTable(String host) { // make sure obj is null. Object obj = null; synchronized (lookupTable) { // If the host isn't in the lookupTable, add it in the // lookuptable and return null. The caller should do // the lookup. if (lookupTable.containsKey(host) == false) { lookupTable.put(host, null); return obj; } // If the host is in the lookupTable, it means that another // thread is trying to look up the address of this host. // This thread should wait. while (lookupTable.containsKey(host)) { try { lookupTable.wait(); } catch (InterruptedException e) { } } } // The other thread has finished looking up the address of // the host. This thread should retry to get the address // from the addressCache. If it doesn't get the address from // the cache, it will try to look up the address itself. obj = getCachedAddress(host); if (obj == null) { synchronized (lookupTable) { lookupTable.put(host, null); } } return obj; } private static void updateLookupTable(String host) { synchronized (lookupTable) { lookupTable.remove(host); lookupTable.notifyAll(); } } /** * Returns an <code>InetAddress</code> object given the raw IP address . * The argument is in network byte order: the highest order * byte of the address is in <code>getAddress()[0]</code>. * * <p> This method doesn't block, i.e. no reverse name service lookup * is performed. * * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array * must be 16 bytes long * * @param addr the raw IP address in network byte order * @return an InetAddress object created from the raw IP address. * @exception UnknownHostException if IP address is of illegal length * @since 1.4 */ public static InetAddress getByAddress(byte[] addr) throws UnknownHostException { return getByAddress(null, addr); } /** * Returns the local host. * * <p>If there is a security manager, its * <code>checkConnect</code> method is called * with the local host name and <code>-1</code> * as its arguments to see if the operation is allowed. * If the operation is not allowed, an InetAddress representing * the loopback address is returned. * * @return the IP address of the local host. * * @exception UnknownHostException if no IP address for the * <code>host</code> could be found. * * @see SecurityManager#checkConnect */ public static InetAddress getLocalHost() throws UnknownHostException { SecurityManager security = System.getSecurityManager(); try { String local = impl.getLocalHostName(); if (security != null) { security.checkConnect(local, -1); } // we are calling getAddressFromNameService directly // to avoid getting localHost from cache InetAddress[] localAddrs; try { localAddrs = (InetAddress[]) InetAddress.getAddressFromNameService(local); } catch (UnknownHostException uhe) { throw new UnknownHostException(local + ": " + uhe.getMessage()); } return localAddrs[0]; } catch (java.lang.SecurityException e) { return impl.loopbackAddress(); } } /** * Perform class load-time initializations. */ private static native void init(); /* * Returns the InetAddress representing anyLocalAddress * (typically 0.0.0.0 or ::0) */ static InetAddress anyLocalAddress() { return impl.anyLocalAddress(); } /* * Load and instantiate an underlying impl class */ static Object loadImpl(String implName) { Object impl; /* * Property "impl.prefix" will be prepended to the classname * of the implementation object we instantiate, to which we * delegate the real work (like native methods). This * property can vary across implementations of the java. * classes. The default is an empty String "". */ String prefix = (String)AccessController.doPrivileged( new GetPropertyAction("impl.prefix", "")); impl = null; try { impl = Class.forName("java.net." + prefix + implName).newInstance(); } catch (ClassNotFoundException e) { System.err.println("Class not found: java.net." + prefix + implName + ":\ncheck impl.prefix property " + "in your properties file."); } catch (InstantiationException e) { System.err.println("Could not instantiate: java.net." + prefix + implName + ":\ncheck impl.prefix property " + "in your properties file."); } catch (IllegalAccessException e) { System.err.println("Cannot access class: java.net." + prefix + implName + ":\ncheck impl.prefix property " + "in your properties file."); } if (impl == null) { try { impl = Class.forName(implName).newInstance(); } catch (Exception e) { throw new Error("System property impl.prefix incorrect"); } } return impl; } /* Check java.net.preferIPv4Stack property. Used by init_IPv6Available() */ private static boolean preferIPv4Stack() { Boolean res = (Boolean) java.security.AccessController.doPrivileged( new sun.security.action.GetBooleanAction( "java.net.preferIPv4Stack")); return res.booleanValue(); }}/* * Simple factory to create the impl */class InetAddressImplFactory { static InetAddressImpl create() { Object o; if (isIPv6Supported()) { o = InetAddress.loadImpl("Inet6AddressImpl"); } else { o = InetAddress.loadImpl("Inet4AddressImpl"); } return (InetAddressImpl)o; } private static native boolean isIPv6Supported();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -