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