InetSocketAddress.java revision c0372d90016d241ac979faa6fa1731f30b6f2a03
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 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 private String hostname; 32 33 private InetAddress addr; 34 35 private int port; 36 37 /** 38 * Creates a socket endpoint with the given port number {@code port} and 39 * no specified address. The range for valid port numbers is between 0 and 40 * 65535 inclusive. 41 * 42 * @param port 43 * the specified port number to which this socket is bound. 44 */ 45 public InetSocketAddress(int port) { 46 this((InetAddress) null, port); 47 } 48 49 /** 50 * Creates a socket endpoint with the given port number {@code port} and 51 * {@code address}. The range for valid port numbers is between 0 and 65535 52 * inclusive. If {@code address} is {@code null} this socket is bound to the 53 * IPv4 wildcard address. 54 * 55 * @param port 56 * the specified port number to which this socket is bound. 57 * @param address 58 * the specified address to which this socket is bound. 59 */ 60 public InetSocketAddress(InetAddress address, int port) { 61 if (port < 0 || port > 65535) { 62 throw new IllegalArgumentException(); 63 } 64 if (address == null) { 65 addr = Inet4Address.ANY; 66 } else { 67 addr = address; 68 } 69 hostname = addr.getHostName(); 70 this.port = port; 71 } 72 73 /** 74 * Creates a socket endpoint with the given port number {@code port} and the 75 * hostname {@code host}. The hostname is tried to be resolved and cannot be 76 * {@code null}. The range for valid port numbers is between 0 and 65535 77 * inclusive. 78 * 79 * @param port 80 * the specified port number to which this socket is bound. 81 * @param host 82 * the specified hostname to which this socket is bound. 83 * @throws SecurityException 84 * if a {@link SecurityManager} is installed and its {@code 85 * checkConnect()} method does not allow the resolving of the 86 * host name. 87 */ 88 public InetSocketAddress(String host, int port) { 89 this(host, port, true); 90 } 91 92 /* 93 * Internal constructor for InetSocketAddress(String, int) and 94 * createUnresolved(String, int); 95 */ 96 InetSocketAddress(String hostname, int port, boolean needResolved) { 97 if (hostname == null || port < 0 || port > 65535) { 98 throw new IllegalArgumentException("host=" + hostname + ", port=" + port); 99 } 100 this.hostname = hostname; 101 this.port = port; 102 103 if (needResolved) { 104 SecurityManager smgr = System.getSecurityManager(); 105 if (smgr != null) { 106 smgr.checkConnect(hostname, port); 107 } 108 try { 109 this.addr = InetAddress.getByName(hostname); 110 this.hostname = null; 111 } catch (UnknownHostException ignored) { 112 } 113 } 114 } 115 116 /** 117 * Creates an {@code InetSocketAddress} without trying to resolve the 118 * hostname into an {@code InetAddress}. The address field is marked as 119 * unresolved. 120 * 121 * @param host 122 * the specified hostname to which this socket is bound. 123 * @param port 124 * the specified port number to which this socket is bound. 125 * @return the created InetSocketAddress instance. 126 * @throws IllegalArgumentException 127 * if the hostname {@code host} is {@code null} or the port is 128 * not in the range between 0 and 65535. 129 */ 130 public static InetSocketAddress createUnresolved(String host, int port) { 131 return new InetSocketAddress(host, port, false); 132 } 133 134 /** 135 * Gets the port number of this socket. 136 * 137 * @return the socket endpoint port number. 138 */ 139 public final int getPort() { 140 return port; 141 } 142 143 /** 144 * Gets the address of this socket. 145 * 146 * @return the socket endpoint address. 147 */ 148 public final InetAddress getAddress() { 149 return addr; 150 } 151 152 /** 153 * Gets the hostname of this socket. 154 * 155 * @return the socket endpoint hostname. 156 */ 157 public final String getHostName() { 158 return (null != addr) ? addr.getHostName() : hostname; 159 } 160 161 /** 162 * Returns whether this socket address is unresolved or not. 163 * 164 * @return {@code true} if this socket address is unresolved, {@code false} 165 * otherwise. 166 */ 167 public final boolean isUnresolved() { 168 return addr == null; 169 } 170 171 /** 172 * Gets a string representation of this socket included the address and the 173 * port number. 174 * 175 * @return the address and port number as a textual representation. 176 */ 177 @Override 178 public String toString() { 179 String host; 180 if (addr != null) { 181 host = addr.toString(); 182 } else { 183 host = hostname; 184 } 185 return host + ":" + port; 186 } 187 188 /** 189 * Compares two socket endpoints and returns true if they are equal. Two 190 * socket endpoints are equal if the IP address or the hostname of both are 191 * equal and they are bound to the same port. 192 * 193 * @param socketAddr 194 * the object to be tested for equality. 195 * @return {@code true} if this socket and the given socket object {@code 196 * socketAddr} are equal, {@code false} otherwise. 197 */ 198 @Override 199 public final boolean equals(Object socketAddr) { 200 if (this == socketAddr) { 201 return true; 202 } 203 if (!(socketAddr instanceof InetSocketAddress)) { 204 return false; 205 } 206 InetSocketAddress iSockAddr = (InetSocketAddress) socketAddr; 207 208 // check the ports as we always need to do this 209 if (port != iSockAddr.port) { 210 return false; 211 } 212 213 // we only use the hostnames in the comparison if the addrs were not 214 // resolved 215 if ((addr == null) && (iSockAddr.addr == null)) { 216 return hostname.equals(iSockAddr.hostname); 217 } 218 219 // addrs were resolved so use them for the comparison 220 if (addr == null) { 221 // if we are here we know iSockAddr is not null so just return 222 // false 223 return false; 224 } 225 return addr.equals(iSockAddr.addr); 226 } 227 228 /** 229 * Gets the hashcode of this socket. 230 * 231 * @return the appropriate hashcode. 232 */ 233 @Override 234 public final int hashCode() { 235 if (addr == null) { 236 return hostname.hashCode() + port; 237 } 238 return addr.hashCode() + port; 239 } 240 241 private void readObject(ObjectInputStream stream) throws IOException, 242 ClassNotFoundException { 243 stream.defaultReadObject(); 244 } 245} 246