| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package java.net; |
| |
| import java.io.IOException; |
| import java.io.ObjectInputStream; |
| |
| /** |
| * This class represents a socket endpoint described by a IP address and a port |
| * number. It is a concrete implementation of {@code SocketAddress} for IP. |
| */ |
| public class InetSocketAddress extends SocketAddress { |
| |
| private static final long serialVersionUID = 5076001401234631237L; |
| |
| // Exactly one of hostname or addr should be set. |
| private final InetAddress addr; |
| private final String hostname; |
| private final int port; |
| |
| /** |
| * @hide internal use only |
| */ |
| public InetSocketAddress() { |
| // These will be filled in the native implementation of recvfrom. |
| this.addr = null; |
| this.hostname = null; |
| this.port = -1; |
| } |
| |
| /** |
| * Creates a socket endpoint with the given port number {@code port} and |
| * no specified address. The range for valid port numbers is between 0 and |
| * 65535 inclusive. |
| * |
| * @param port |
| * the specified port number to which this socket is bound. |
| */ |
| public InetSocketAddress(int port) { |
| this((InetAddress) null, port); |
| } |
| |
| /** |
| * Creates a socket endpoint with the given port number {@code port} and |
| * {@code address}. The range for valid port numbers is between 0 and 65535 |
| * inclusive. If {@code address} is {@code null} this socket is bound to the |
| * IPv4 wildcard address. |
| * |
| * @param port |
| * the specified port number to which this socket is bound. |
| * @param address |
| * the specified address to which this socket is bound. |
| */ |
| public InetSocketAddress(InetAddress address, int port) { |
| if (port < 0 || port > 65535) { |
| throw new IllegalArgumentException("port=" + port); |
| } |
| this.addr = (address == null) ? Inet4Address.ANY : address; |
| this.hostname = null; |
| this.port = port; |
| } |
| |
| /** |
| * Creates a socket endpoint with the given port number {@code port} and the |
| * hostname {@code host}. The hostname is tried to be resolved and cannot be |
| * {@code null}. The range for valid port numbers is between 0 and 65535 |
| * inclusive. |
| * |
| * @param port |
| * the specified port number to which this socket is bound. |
| * @param host |
| * the specified hostname to which this socket is bound. |
| */ |
| public InetSocketAddress(String host, int port) { |
| this(host, port, true); |
| } |
| |
| /* |
| * Internal constructor for InetSocketAddress(String, int) and |
| * createUnresolved(String, int); |
| */ |
| InetSocketAddress(String hostname, int port, boolean needResolved) { |
| if (hostname == null || port < 0 || port > 65535) { |
| throw new IllegalArgumentException("host=" + hostname + ", port=" + port); |
| } |
| |
| InetAddress addr = null; |
| if (needResolved) { |
| try { |
| addr = InetAddress.getByName(hostname); |
| hostname = null; |
| } catch (UnknownHostException ignored) { |
| } |
| } |
| this.addr = addr; |
| this.hostname = hostname; |
| this.port = port; |
| } |
| |
| /** |
| * Creates an {@code InetSocketAddress} without trying to resolve the |
| * hostname into an {@code InetAddress}. The address field is marked as |
| * unresolved. |
| * |
| * @param host |
| * the specified hostname to which this socket is bound. |
| * @param port |
| * the specified port number to which this socket is bound. |
| * @return the created InetSocketAddress instance. |
| * @throws IllegalArgumentException |
| * if the hostname {@code host} is {@code null} or the port is |
| * not in the range between 0 and 65535. |
| */ |
| public static InetSocketAddress createUnresolved(String host, int port) { |
| return new InetSocketAddress(host, port, false); |
| } |
| |
| /** |
| * Gets the port number of this socket. |
| * |
| * @return the socket endpoint port number. |
| */ |
| public final int getPort() { |
| return port; |
| } |
| |
| /** |
| * Gets the address of this socket. |
| * |
| * @return the socket endpoint address. |
| */ |
| public final InetAddress getAddress() { |
| return addr; |
| } |
| |
| /** |
| * Returns the hostname, doing a reverse lookup on the {@code InetAddress} if no |
| * hostname string was provided at construction time. |
| */ |
| public final String getHostName() { |
| return (addr != null) ? addr.getHostName() : hostname; |
| } |
| |
| /** |
| * Returns the hostname if known, or the result of {@code InetAddress.getHostAddress}. |
| * Unlike {@link #getHostName}, this method will never cause a DNS lookup. |
| * @since 1.7 |
| * @hide 1.7 - remember to add a link in the getHostName documentation! |
| */ |
| public final String getHostString() { |
| return (hostname != null) ? hostname : addr.getHostAddress(); |
| } |
| |
| /** |
| * Returns whether this socket address is unresolved or not. |
| * |
| * @return {@code true} if this socket address is unresolved, {@code false} |
| * otherwise. |
| */ |
| public final boolean isUnresolved() { |
| return addr == null; |
| } |
| |
| /** |
| * Returns a string containing the address (or the hostname for an |
| * unresolved {@code InetSocketAddress}) and port number. |
| * For example: {@code "www.google.com/74.125.224.115:80"} or {@code "/127.0.0.1:80"}. |
| */ |
| @Override public String toString() { |
| return ((addr != null) ? addr.toString() : hostname) + ":" + port; |
| } |
| |
| /** |
| * Compares two socket endpoints and returns true if they are equal. Two |
| * socket endpoints are equal if the IP address or the hostname of both are |
| * equal and they are bound to the same port. |
| * |
| * @param socketAddr |
| * the object to be tested for equality. |
| * @return {@code true} if this socket and the given socket object {@code |
| * socketAddr} are equal, {@code false} otherwise. |
| */ |
| @Override |
| public final boolean equals(Object socketAddr) { |
| if (this == socketAddr) { |
| return true; |
| } |
| if (!(socketAddr instanceof InetSocketAddress)) { |
| return false; |
| } |
| InetSocketAddress iSockAddr = (InetSocketAddress) socketAddr; |
| |
| // check the ports as we always need to do this |
| if (port != iSockAddr.port) { |
| return false; |
| } |
| |
| // we only use the hostnames in the comparison if the addrs were not |
| // resolved |
| if ((addr == null) && (iSockAddr.addr == null)) { |
| return hostname.equals(iSockAddr.hostname); |
| } |
| |
| // addrs were resolved so use them for the comparison |
| if (addr == null) { |
| // if we are here we know iSockAddr is not null so just return |
| // false |
| return false; |
| } |
| return addr.equals(iSockAddr.addr); |
| } |
| |
| @Override |
| public final int hashCode() { |
| if (addr == null) { |
| return hostname.hashCode() + port; |
| } |
| return addr.hashCode() + port; |
| } |
| |
| private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { |
| stream.defaultReadObject(); |
| } |
| } |