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