1. /*
  2. * @(#)ServerSocket.java 1.37 01/11/29
  3. *
  4. * Copyright 2002 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.IOException;
  9. import java.io.FileDescriptor;
  10. /**
  11. * This class implements server sockets. A server socket waits for
  12. * requests to come in over the network. It performs some operation
  13. * based on that request, and then possibly returns a result to the requester.
  14. * <p>
  15. * The actual work of the server socket is performed by an instance
  16. * of the <code>SocketImpl</code> class. An application can
  17. * change the socket factory that creates the socket
  18. * implementation to configure itself to create sockets
  19. * appropriate to the local firewall.
  20. *
  21. * @author unascribed
  22. * @version 1.37, 11/29/01
  23. * @see java.net.SocketImpl
  24. * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  25. * @since JDK1.0
  26. */
  27. public
  28. class ServerSocket {
  29. /**
  30. * The implementation of this Socket.
  31. */
  32. private SocketImpl impl;
  33. /**
  34. * Creates an unconnected server socket. Note: this method
  35. * should not be public.
  36. * @exception IOException IO error when opening the socket.
  37. */
  38. private ServerSocket() throws IOException {
  39. impl = (factory != null) ? factory.createSocketImpl() :
  40. new PlainSocketImpl();
  41. }
  42. /**
  43. * Creates a server socket on a specified port. A port of
  44. * <code>0</code> creates a socket on any free port.
  45. * <p>
  46. * The maximum queue length for incoming connection indications (a
  47. * request to connect) is set to <code>50</code>. If a connection
  48. * indication arrives when the queue is full, the connection is refused.
  49. * <p>
  50. * If the application has specified a server socket factory, that
  51. * factory's <code>createSocketImpl</code> method is called to create
  52. * the actual socket implementation. Otherwise a "plain" socket is created.
  53. * <p>
  54. * If there is a security manager,
  55. * its <code>checkListen</code> method is called
  56. * with the <code>port</code> argument
  57. * as its argument to ensure the operation is allowed.
  58. * This could result in a SecurityException.
  59. *
  60. * @param port the port number, or <code>0</code> to use any
  61. * free port.
  62. *
  63. * @exception IOException if an I/O error occurs when opening the socket.
  64. * @exception SecurityException
  65. * if a security manager exists and its <code>checkListen</code>
  66. * method doesn't allow the operation.
  67. *
  68. * @see java.net.SocketImpl
  69. * @see java.net.SocketImplFactory#createSocketImpl()
  70. * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  71. * @see SecurityManager#checkListen
  72. */
  73. public ServerSocket(int port) throws IOException {
  74. this(port, 50, null);
  75. }
  76. /**
  77. * Creates a server socket and binds it to the specified local port
  78. * number. A port number of <code>0</code> creates a socket on any
  79. * free port.
  80. * <p>
  81. * The maximum queue length for incoming connection indications (a
  82. * request to connect) is set to the <code>backlog</code> parameter. If
  83. * a connection indication arrives when the queue is full, the
  84. * connection is refused.
  85. * <p>
  86. * If the application has specified a server socket factory, that
  87. * factory's <code>createSocketImpl</code> method is called to create
  88. * the actual socket implementation. Otherwise a "plain" socket is created.
  89. * <p>
  90. * If there is a security manager,
  91. * its <code>checkListen</code> method is called
  92. * with the <code>port</code> argument
  93. * as its argument to ensure the operation is allowed.
  94. * This could result in a SecurityException.
  95. *
  96. * @param port the specified port, or <code>0</code> to use
  97. * any free port.
  98. * @param backlog the maximum length of the queue.
  99. *
  100. * @exception IOException if an I/O error occurs when opening the socket.
  101. * @exception SecurityException
  102. * if a security manager exists and its <code>checkListen</code>
  103. * method doesn't allow the operation.
  104. *
  105. * @see java.net.SocketImpl
  106. * @see java.net.SocketImplFactory#createSocketImpl()
  107. * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  108. * @see SecurityManager#checkListen
  109. */
  110. public ServerSocket(int port, int backlog) throws IOException {
  111. this(port, backlog, null);
  112. }
  113. /**
  114. * Create a server with the specified port, listen backlog, and
  115. * local IP address to bind to. The <i>bindAddr</i> argument
  116. * can be used on a multi-homed host for a ServerSocket that
  117. * will only accept connect requests to one of its addresses.
  118. * If <i>bindAddr</i> is null, it will default accepting
  119. * connections on any/all local addresses.
  120. * The port must be between 0 and 65535, inclusive.
  121. *
  122. * <P>If there is a security manager, this method
  123. * calls its <code>checkListen</code> method
  124. * with the <code>port</code> argument
  125. * as its argument to ensure the operation is allowed.
  126. * This could result in a SecurityException.
  127. *
  128. * <P>
  129. * @param port the local TCP port
  130. * @param backlog the listen backlog
  131. * @param bindAddr the local InetAddress the server will bind to
  132. *
  133. * @throws SecurityException
  134. * if a security manager exists and its <code>checkListen</code>
  135. * method doesn't allow the operation.
  136. *
  137. * @see SocketConstants
  138. * @see SocketOption
  139. * @see SocketImpl
  140. * @see SecurityManager#checkListen
  141. * @since JDK1.1
  142. */
  143. public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {
  144. this();
  145. if (port < 0 || port > 0xFFFF)
  146. throw new IllegalArgumentException(
  147. "Port value out of range: " + port);
  148. try {
  149. SecurityManager security = System.getSecurityManager();
  150. if (security != null) {
  151. security.checkListen(port);
  152. }
  153. impl.create(true); // a stream socket
  154. if (bindAddr == null)
  155. bindAddr = InetAddress.anyLocalAddress;
  156. impl.bind(bindAddr, port);
  157. impl.listen(backlog);
  158. } catch(SecurityException e) {
  159. impl.close();
  160. throw e;
  161. } catch(IOException e) {
  162. impl.close();
  163. throw e;
  164. }
  165. }
  166. /**
  167. * Returns the local address of this server socket.
  168. *
  169. * @return the address to which this socket is connected,
  170. * or <code>null</code> if the socket is not yet connected.
  171. */
  172. public InetAddress getInetAddress() {
  173. return impl.getInetAddress();
  174. }
  175. /**
  176. * Returns the port on which this socket is listening.
  177. *
  178. * @return the port number to which this socket is listening.
  179. */
  180. public int getLocalPort() {
  181. return impl.getLocalPort();
  182. }
  183. /**
  184. * Listens for a connection to be made to this socket and accepts
  185. * it. The method blocks until a connection is made.
  186. *
  187. * <p>A new Socket <code>s</code> is created and, if there is a security manager,
  188. * the security manager's <code>checkAccept</code> method is called
  189. * with <code>s.getInetAddress().getHostAddress()</code> and
  190. * <code>s.getPort()</code>
  191. * as its arguments to ensure the operation is allowed.
  192. * This could result in a SecurityException.
  193. *
  194. * @exception IOException if an I/O error occurs when waiting for a
  195. * connection.
  196. * @exception SecurityException if a security manager exists and its
  197. * <code>checkListen</code> method doesn't allow the operation.
  198. *
  199. * @see SecurityManager#checkAccept
  200. */
  201. public Socket accept() throws IOException {
  202. Socket s = new Socket();
  203. implAccept(s);
  204. return s;
  205. }
  206. /**
  207. * Subclasses of ServerSocket use this method to override accept()
  208. * to return their own subclass of socket. So a FooServerSocket
  209. * will typically hand this method an <i>empty</i> FooSocket(). On
  210. * return from implAccept the FooSocket will be connected to a client.
  211. *
  212. * @since JDK1.1
  213. */
  214. protected final void implAccept(Socket s) throws IOException {
  215. SocketImpl si = s.impl;
  216. try {
  217. s.impl = null;
  218. si.address = new InetAddress();
  219. si.fd = new FileDescriptor();
  220. impl.accept(si);
  221. SecurityManager security = System.getSecurityManager();
  222. if (security != null) {
  223. security.checkAccept(si.getInetAddress().getHostAddress(),
  224. si.getPort());
  225. }
  226. } catch (IOException e) {
  227. si.reset();
  228. s.impl = si;
  229. throw e;
  230. } catch (SecurityException e) {
  231. si.reset();
  232. s.impl = si;
  233. throw e;
  234. }
  235. s.impl = si;
  236. }
  237. /**
  238. * Closes this socket.
  239. *
  240. * @exception IOException if an I/O error occurs when closing the socket.
  241. */
  242. public void close() throws IOException {
  243. impl.close();
  244. }
  245. /** Enable/disable SO_TIMEOUT with the specified timeout, in
  246. * milliseconds. With this option set to a non-zero timeout,
  247. * a call to accept() for this ServerSocket
  248. * will block for only this amount of time. If the timeout expires,
  249. * a <B>java.io.InterruptedIOException</B> is raised, though the
  250. * ServerSocket is still valid. The option <B>must</B> be enabled
  251. * prior to entering the blocking operation to have effect. The
  252. * timeout must be > 0.
  253. * A timeout of zero is interpreted as an infinite timeout.
  254. *
  255. * @since JDK1.1
  256. */
  257. public synchronized void setSoTimeout(int timeout) throws SocketException {
  258. impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
  259. }
  260. /** Retrive setting for SO_TIMEOUT. 0 returns implies that the
  261. * option is disabled (i.e., timeout of infinity).
  262. *
  263. * @since JDK1.1
  264. */
  265. public synchronized int getSoTimeout() throws IOException {
  266. Object o = impl.getOption(SocketOptions.SO_TIMEOUT);
  267. /* extra type safety */
  268. if (o instanceof Integer) {
  269. return ((Integer) o).intValue();
  270. } else {
  271. return 0;
  272. }
  273. }
  274. /**
  275. * Returns the implementation address and implementation port of
  276. * this socket as a <code>String</code>.
  277. *
  278. * @return a string representation of this socket.
  279. */
  280. public String toString() {
  281. return "ServerSocket[addr=" + impl.getInetAddress() +
  282. ",port=" + impl.getPort() +
  283. ",localport=" + impl.getLocalPort() + "]";
  284. }
  285. /**
  286. * The factory for all server sockets.
  287. */
  288. private static SocketImplFactory factory;
  289. /**
  290. * Sets the server socket implementation factory for the
  291. * application. The factory can be specified only once.
  292. * <p>
  293. * When an application creates a new server socket, the socket
  294. * implementation factory's <code>createSocketImpl</code> method is
  295. * called to create the actual socket implementation.
  296. * <p>
  297. * If there is a security manager, this method first calls
  298. * the security manager's <code>checkSetFactory</code> method
  299. * to ensure the operation is allowed.
  300. * This could result in a SecurityException.
  301. *
  302. * @param fac the desired factory.
  303. * @exception IOException if an I/O error occurs when setting the
  304. * socket factory.
  305. * @exception SocketException if the factory has already been defined.
  306. * @exception SecurityException if a security manager exists and its
  307. * <code>checkSetFactory</code> method doesn't allow the operation.
  308. * @see java.net.SocketImplFactory#createSocketImpl()
  309. * @see SecurityManager#checkSetFactory
  310. */
  311. public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException {
  312. if (factory != null) {
  313. throw new SocketException("factory already defined");
  314. }
  315. SecurityManager security = System.getSecurityManager();
  316. if (security != null) {
  317. security.checkSetFactory();
  318. }
  319. factory = fac;
  320. }
  321. }