1. /*
  2. * @(#)InetSocketAddress.java 1.15 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.net;
  8. import java.io.ObjectInputStream;
  9. import java.io.IOException;
  10. import java.io.InvalidObjectException;
  11. /**
  12. *
  13. * This class implements an IP Socket Address (IP address + port number)
  14. * It can also be a pair (hostname + port number), in which case an attempt
  15. * will be made to resolve the hostname. If resolution fails then the address
  16. * is said to be <I>unresolved</I> but can still be used on some circumstances
  17. * like connecting through a proxy.
  18. * <p>
  19. * It provides an immutable object used by sockets for binding, connecting, or
  20. * as returned values.
  21. * <p>
  22. * The <i>wildcard</i> is a special local IP address. It usually means "any"
  23. * and can only be used for <code>bind</code> operations.
  24. *
  25. * @see java.net.Socket
  26. * @see java.net.ServerSocket
  27. * @since 1.4
  28. */
  29. public class InetSocketAddress extends SocketAddress {
  30. /* The hostname of the Socket Address
  31. * @serial
  32. */
  33. private String hostname = null;
  34. /* The IP address of the Socket Address
  35. * @serial
  36. */
  37. private InetAddress addr = null;
  38. /* The port number of the Socket Address
  39. * @serial
  40. */
  41. private int port;
  42. private static final long serialVersionUID = 5076001401234631237L;
  43. /**
  44. * Creates a socket address where the IP address is the wildcard address
  45. * and the port number a specified value.
  46. * <p>
  47. * A valid port value is between 0 and 65535.
  48. * A port number of <code>zero</code> will let the system pick up an
  49. * ephemeral port in a <code>bind</code> operation.
  50. * <p>
  51. * @param port The port number
  52. * @throws IllegalArgumentException if the port parameter is outside the specified
  53. * range of valid port values.
  54. */
  55. public InetSocketAddress(int port) {
  56. this(InetAddress.anyLocalAddress(), port);
  57. }
  58. /**
  59. *
  60. * Creates a socket address from an IP address and a port number.
  61. * <p>
  62. * A valid port value is between 0 and 65535.
  63. * A port number of <code>zero</code> will let the system pick up an
  64. * ephemeral port in a <code>bind</code> operation.
  65. * <P>
  66. * A <code>null</code> address will assign the <i>wildcard</i> address.
  67. * <p>
  68. * @param addr The IP address
  69. * @param port The port number
  70. * @throws IllegalArgumentException if the port parameter is outside the specified
  71. * range of valid port values.
  72. */
  73. public InetSocketAddress(InetAddress addr, int port) {
  74. if (port < 0 || port > 0xFFFF) {
  75. throw new IllegalArgumentException("port out of range:" + port);
  76. }
  77. this.port = port;
  78. if (addr == null)
  79. this.addr = InetAddress.anyLocalAddress();
  80. else
  81. this.addr = addr;
  82. }
  83. /**
  84. *
  85. * Creates a socket address from a hostname and a port number.
  86. * <p>
  87. * An attempt will be made to resolve the hostname into an InetAddress.
  88. * If that attempt fails, the address will be flagged as <I>unresolved</I>.
  89. * <p>
  90. * A valid port value is between 0 and 65535.
  91. * A port number of <code>zero</code> will let the system pick up an
  92. * ephemeral port in a <code>bind</code> operation.
  93. * <P>
  94. * @param hostname the Host name
  95. * @param port The port number
  96. * @throws IllegalArgumentException if the port parameter is outside the range
  97. * of valid port values, or if the hostname parameter is <TT>null</TT>.
  98. * @see #isUnresolved()
  99. */
  100. public InetSocketAddress(String hostname, int port) {
  101. if (port < 0 || port > 0xFFFF) {
  102. throw new IllegalArgumentException("port out of range:" + port);
  103. }
  104. if (hostname == null) {
  105. throw new IllegalArgumentException("hostname can't be null");
  106. }
  107. try {
  108. addr = InetAddress.getByName(hostname);
  109. } catch(UnknownHostException e) {
  110. this.hostname = hostname;
  111. addr = null;
  112. }
  113. this.port = port;
  114. }
  115. private void readObject(ObjectInputStream s)
  116. throws IOException, ClassNotFoundException {
  117. s.defaultReadObject();
  118. // Check that our invariants are satisfied
  119. if (port < 0 || port > 0xFFFF) {
  120. throw new InvalidObjectException("port out of range:" + port);
  121. }
  122. if (hostname == null && addr == null) {
  123. throw new InvalidObjectException("hostname and addr " +
  124. "can't both be null");
  125. }
  126. }
  127. /**
  128. * Gets the port number.
  129. *
  130. * @return the port number.
  131. */
  132. public final int getPort() {
  133. return port;
  134. }
  135. /**
  136. *
  137. * Gets the <code>InetAddress</code>.
  138. *
  139. * @return the InetAdress or <code>null</code> if it is unresolved.
  140. */
  141. public final InetAddress getAddress() {
  142. return addr;
  143. }
  144. /**
  145. * Gets the <code>hostname</code>.
  146. *
  147. * @return the hostname part of the address.
  148. */
  149. public final String getHostName() {
  150. if (hostname != null)
  151. return hostname;
  152. if (addr != null)
  153. return addr.getHostName();
  154. return null;
  155. }
  156. /**
  157. * Checks wether the address has been resolved or not.
  158. *
  159. * @return <code>true</code> if the hostname couldn't be resolved into
  160. * an <code>InetAddress</code>.
  161. */
  162. public final boolean isUnresolved() {
  163. return addr == null;
  164. }
  165. /**
  166. * Constructs a string representation of this InetSocketAddress.
  167. * This String is constructed by calling toString() on the InetAddress
  168. * and concatenating the port number (with a colon). If the address
  169. * is unresolved then the part before the colon will only contain the hostname.
  170. *
  171. * @return a string representation of this object.
  172. */
  173. public String toString() {
  174. if (isUnresolved()) {
  175. return hostname + ":" + port;
  176. } else {
  177. return addr.toString() + ":" + port;
  178. }
  179. }
  180. /**
  181. * Compares this object against the specified object.
  182. * The result is <code>true</code> if and only if the argument is
  183. * not <code>null</code> and it represents the same address as
  184. * this object.
  185. * <p>
  186. * Two instances of <code>InetSocketAddress</code> represent the same
  187. * address if both the InetAddresses (or hostnames if it is unresolved) and port
  188. * numbers are equal.
  189. * If both addresses are unresolved, then the hostname & the port number
  190. * are compared.
  191. *
  192. * @param obj the object to compare against.
  193. * @return <code>true</code> if the objects are the same;
  194. * <code>false</code> otherwise.
  195. * @see java.net.InetAddress#equals(java.lang.Object)
  196. */
  197. public final boolean equals(Object obj) {
  198. if (obj == null || !(obj instanceof InetSocketAddress))
  199. return false;
  200. InetSocketAddress sockAddr = (InetSocketAddress) obj;
  201. boolean sameIP = false;
  202. if (this.addr != null)
  203. sameIP = this.addr.equals(sockAddr.addr);
  204. else if (this.hostname != null)
  205. sameIP = (sockAddr.addr == null) &&
  206. this.hostname.equals(sockAddr.hostname);
  207. else
  208. sameIP = (sockAddr.addr == null) && (sockAddr.hostname == null);
  209. return sameIP && (this.port == sockAddr.port);
  210. }
  211. /**
  212. * Returns a hashcode for this socket address.
  213. *
  214. * @return a hash code value for this socket address.
  215. */
  216. public final int hashCode() {
  217. if (addr != null)
  218. return addr.hashCode() + port;
  219. if (hostname != null)
  220. return hostname.hashCode() + port;
  221. return port;
  222. }
  223. }