1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.net; 19 20import java.io.IOException; 21import java.io.ObjectInputStream; 22 23/** 24 * This class represents the address of a socket endpoint described by a IP address and a port 25 * number. It is a concrete implementation of {@code SocketAddress} for IP. 26 */ 27public class InetSocketAddress extends SocketAddress { 28 29 private static final long serialVersionUID = 5076001401234631237L; 30 31 // Exactly one of hostname or addr should be set. 32 private final InetAddress addr; 33 private final String hostname; 34 private final int port; 35 36 /** 37 * @hide internal use only 38 */ 39 public InetSocketAddress() { 40 // These will be filled in the native implementation of recvfrom. 41 this.addr = null; 42 this.hostname = null; 43 this.port = -1; 44 } 45 46 /** 47 * Creates a socket endpoint with the given port number {@code port} and 48 * no specified address. The range for valid port numbers is between 0 and 49 * 65535 inclusive. 50 * 51 * @param port the port number of the socket endpoint. 52 */ 53 public InetSocketAddress(int port) { 54 this((InetAddress) null, port); 55 } 56 57 /** 58 * Creates a socket endpoint with the given port number {@code port} and 59 * {@code address}. The range for valid port numbers is between 0 and 65535 60 * inclusive. If {@code address} is {@code null} the address is set to a 61 * wildcard address. 62 * 63 * @param address the address of the socket endpoint. 64 * @param port the port number of the socket endpoint. 65 */ 66 public InetSocketAddress(InetAddress address, int port) { 67 if (port < 0 || port > 65535) { 68 throw new IllegalArgumentException("port=" + port); 69 } 70 this.addr = (address == null) ? Inet6Address.ANY : address; 71 this.hostname = null; 72 this.port = port; 73 } 74 75 /** 76 * Creates a socket endpoint with the given port number {@code port} and the 77 * hostname {@code host}. The hostname is tried to be resolved and cannot be 78 * {@code null}. The range for valid port numbers is between 0 and 65535 79 * inclusive. 80 * 81 * @param host the hostname of the socket endpoint. 82 * @param port the port number of the socket endpoint. 83 */ 84 public InetSocketAddress(String host, int port) { 85 this(host, port, true); 86 } 87 88 /* 89 * Internal constructor for InetSocketAddress(String, int) and 90 * createUnresolved(String, int); 91 */ 92 InetSocketAddress(String hostname, int port, boolean needResolved) { 93 if (hostname == null || port < 0 || port > 65535) { 94 throw new IllegalArgumentException("host=" + hostname + ", port=" + port); 95 } 96 97 InetAddress addr = null; 98 if (needResolved) { 99 try { 100 addr = InetAddress.getByName(hostname); 101 hostname = null; 102 } catch (UnknownHostException ignored) { 103 } 104 } 105 this.addr = addr; 106 this.hostname = hostname; 107 this.port = port; 108 } 109 110 /** 111 * Creates an {@code InetSocketAddress} without trying to resolve the 112 * hostname into an {@code InetAddress}. The address field is marked as 113 * unresolved. 114 * 115 * @param host the hostname of the socket endpoint. 116 * @param port the port number of the socket endpoint. 117 * @return the created InetSocketAddress instance. 118 * @throws IllegalArgumentException if the hostname {@code host} is {@code null} or the port is 119 * not in the range between 0 and 65535. 120 */ 121 public static InetSocketAddress createUnresolved(String host, int port) { 122 return new InetSocketAddress(host, port, false); 123 } 124 125 /** 126 * Returns the socket endpoint's port. 127 */ 128 public final int getPort() { 129 return port; 130 } 131 132 /** 133 * Returns the socket endpoint's address. 134 */ 135 public final InetAddress getAddress() { 136 return addr; 137 } 138 139 /** 140 * Returns the hostname, doing a reverse DNS lookup on the {@code InetAddress} if no 141 * hostname string was provided at construction time. Use {@link #getHostString} to 142 * avoid the reverse DNS lookup. 143 */ 144 public final String getHostName() { 145 return (addr != null) ? addr.getHostName() : hostname; 146 } 147 148 /** 149 * Returns the hostname if known, or the result of {@code InetAddress.getHostAddress}. 150 * Unlike {@link #getHostName}, this method will never cause a DNS lookup. 151 * @since 1.7 152 */ 153 public final String getHostString() { 154 return (hostname != null) ? hostname : addr.getHostString(); 155 } 156 157 /** 158 * Returns whether this socket address is unresolved or not. 159 * 160 * @return {@code true} if this socket address is unresolved, {@code false} 161 * otherwise. 162 */ 163 public final boolean isUnresolved() { 164 return addr == null; 165 } 166 167 /** 168 * Returns a string containing the address (or the hostname for an 169 * unresolved {@code InetSocketAddress}) and port number. 170 * For example: {@code "www.google.com/74.125.224.115:80"} or {@code "/127.0.0.1:80"}. 171 */ 172 @Override public String toString() { 173 return ((addr != null) ? addr.toString() : hostname) + ":" + port; 174 } 175 176 /** 177 * Compares two socket endpoints and returns true if they are equal. Two 178 * socket endpoints are equal if the IP address or the hostname of both are 179 * equal and they are bound to the same port. 180 * 181 * @param socketAddr the object to be tested for equality. 182 * @return {@code true} if this socket endpoint and the given socket endpoint {@code 183 * socketAddr} are equal, {@code false} otherwise. 184 */ 185 @Override 186 public final boolean equals(Object socketAddr) { 187 if (this == socketAddr) { 188 return true; 189 } 190 if (!(socketAddr instanceof InetSocketAddress)) { 191 return false; 192 } 193 InetSocketAddress iSockAddr = (InetSocketAddress) socketAddr; 194 195 // check the ports as we always need to do this 196 if (port != iSockAddr.port) { 197 return false; 198 } 199 200 // we only use the hostnames in the comparison if the addrs were not 201 // resolved 202 if ((addr == null) && (iSockAddr.addr == null)) { 203 return hostname.equals(iSockAddr.hostname); 204 } 205 206 // addrs were resolved so use them for the comparison 207 if (addr == null) { 208 // if we are here we know iSockAddr is not null so just return 209 // false 210 return false; 211 } 212 return addr.equals(iSockAddr.addr); 213 } 214 215 @Override 216 public final int hashCode() { 217 if (addr == null) { 218 return hostname.hashCode() + port; 219 } 220 return addr.hashCode() + port; 221 } 222 223 private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { 224 stream.defaultReadObject(); 225 } 226} 227