1. /*
  2. * @(#)ServerSocket.java 1.75 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.FileDescriptor;
  9. import java.io.IOException;
  10. import java.nio.channels.ServerSocketChannel;
  11. import java.security.AccessController;
  12. import java.security.PrivilegedExceptionAction;
  13. /**
  14. * This class implements server sockets. A server socket waits for
  15. * requests to come in over the network. It performs some operation
  16. * based on that request, and then possibly returns a result to the requester.
  17. * <p>
  18. * The actual work of the server socket is performed by an instance
  19. * of the <code>SocketImpl</code> class. An application can
  20. * change the socket factory that creates the socket
  21. * implementation to configure itself to create sockets
  22. * appropriate to the local firewall.
  23. *
  24. * @author unascribed
  25. * @version 1.75, 01/23/03
  26. * @see java.net.SocketImpl
  27. * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  28. * @see java.nio.channels.ServerSocketChannel
  29. * @since JDK1.0
  30. */
  31. public
  32. class ServerSocket {
  33. /**
  34. * Various states of this socket.
  35. */
  36. private boolean created = false;
  37. private boolean bound = false;
  38. private boolean closed = false;
  39. private Object closeLock = new Object();
  40. /**
  41. * The implementation of this Socket.
  42. */
  43. private SocketImpl impl;
  44. /**
  45. * Are we using an older SocketImpl?
  46. */
  47. private boolean oldImpl = false;
  48. /**
  49. * Creates an unbound server socket.
  50. *
  51. * @exception IOException IO error when opening the socket.
  52. * @revised 1.4
  53. */
  54. public ServerSocket() throws IOException {
  55. setImpl();
  56. }
  57. /**
  58. * Creates a server socket, bound to the specified port. A port of
  59. * <code>0</code> creates a socket on any free port.
  60. * <p>
  61. * The maximum queue length for incoming connection indications (a
  62. * request to connect) is set to <code>50</code>. If a connection
  63. * indication arrives when the queue is full, the connection is refused.
  64. * <p>
  65. * If the application has specified a server socket factory, that
  66. * factory's <code>createSocketImpl</code> method is called to create
  67. * the actual socket implementation. Otherwise a "plain" socket is created.
  68. * <p>
  69. * If there is a security manager,
  70. * its <code>checkListen</code> method is called
  71. * with the <code>port</code> argument
  72. * as its argument to ensure the operation is allowed.
  73. * This could result in a SecurityException.
  74. *
  75. *
  76. * @param port the port number, or <code>0</code> to use any
  77. * free port.
  78. *
  79. * @exception IOException if an I/O error occurs when opening the socket.
  80. * @exception SecurityException
  81. * if a security manager exists and its <code>checkListen</code>
  82. * method doesn't allow the operation.
  83. *
  84. * @see java.net.SocketImpl
  85. * @see java.net.SocketImplFactory#createSocketImpl()
  86. * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  87. * @see SecurityManager#checkListen
  88. */
  89. public ServerSocket(int port) throws IOException {
  90. this(port, 50, null);
  91. }
  92. /**
  93. * Creates a server socket and binds it to the specified local port
  94. * number, with the specified backlog.
  95. * A port number of <code>0</code> creates a socket on any
  96. * free port.
  97. * <p>
  98. * The maximum queue length for incoming connection indications (a
  99. * request to connect) is set to the <code>backlog</code> parameter. If
  100. * a connection indication arrives when the queue is full, the
  101. * connection is refused.
  102. * <p>
  103. * If the application has specified a server socket factory, that
  104. * factory's <code>createSocketImpl</code> method is called to create
  105. * the actual socket implementation. Otherwise a "plain" socket is created.
  106. * <p>
  107. * If there is a security manager,
  108. * its <code>checkListen</code> method is called
  109. * with the <code>port</code> argument
  110. * as its argument to ensure the operation is allowed.
  111. * This could result in a SecurityException.
  112. *
  113. * <P>The <code>backlog</code> argument must be a positive
  114. * value greater than 0. If the value passed if equal or less
  115. * than 0, then the default value will be assumed.
  116. * <P>
  117. *
  118. * @param port the specified port, or <code>0</code> to use
  119. * any free port.
  120. * @param backlog the maximum length of the queue.
  121. *
  122. * @exception IOException if an I/O error occurs when opening the socket.
  123. * @exception SecurityException
  124. * if a security manager exists and its <code>checkListen</code>
  125. * method doesn't allow the operation.
  126. *
  127. * @see java.net.SocketImpl
  128. * @see java.net.SocketImplFactory#createSocketImpl()
  129. * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  130. * @see SecurityManager#checkListen
  131. */
  132. public ServerSocket(int port, int backlog) throws IOException {
  133. this(port, backlog, null);
  134. }
  135. /**
  136. * Create a server with the specified port, listen backlog, and
  137. * local IP address to bind to. The <i>bindAddr</i> argument
  138. * can be used on a multi-homed host for a ServerSocket that
  139. * will only accept connect requests to one of its addresses.
  140. * If <i>bindAddr</i> is null, it will default accepting
  141. * connections on any/all local addresses.
  142. * The port must be between 0 and 65535, inclusive.
  143. *
  144. * <P>If there is a security manager, this method
  145. * calls its <code>checkListen</code> method
  146. * with the <code>port</code> argument
  147. * as its argument to ensure the operation is allowed.
  148. * This could result in a SecurityException.
  149. *
  150. * <P>The <code>backlog</code> argument must be a positive
  151. * value greater than 0. If the value passed if equal or less
  152. * than 0, then the default value will be assumed.
  153. * <P>
  154. * @param port the local TCP port
  155. * @param backlog the listen backlog
  156. * @param bindAddr the local InetAddress the server will bind to
  157. *
  158. * @throws SecurityException if a security manager exists and
  159. * its <code>checkListen</code> method doesn't allow the operation.
  160. *
  161. * @throws IOException if an I/O error occurs when opening the socket.
  162. *
  163. * @see SocketOptions
  164. * @see SocketImpl
  165. * @see SecurityManager#checkListen
  166. * @since JDK1.1
  167. */
  168. public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {
  169. setImpl();
  170. if (port < 0 || port > 0xFFFF)
  171. throw new IllegalArgumentException(
  172. "Port value out of range: " + port);
  173. if (backlog < 1)
  174. backlog = 50;
  175. try {
  176. bind(new InetSocketAddress(bindAddr, port), backlog);
  177. } catch(SecurityException e) {
  178. close();
  179. throw e;
  180. } catch(IOException e) {
  181. close();
  182. throw e;
  183. }
  184. }
  185. /**
  186. * Get the <code>SocketImpl</code> attached to this socket, creating
  187. * it if necessary.
  188. *
  189. * @return the <code>SocketImpl</code> attached to that ServerSocket.
  190. * @throws SocketException if creation fails.
  191. * @since 1.4
  192. */
  193. SocketImpl getImpl() throws SocketException {
  194. if (!created)
  195. createImpl();
  196. return impl;
  197. }
  198. private void checkOldImpl() {
  199. if (impl == null)
  200. return;
  201. // SocketImpl.connect() is a protected method, therefore we need to use
  202. // getDeclaredMethod, therefore we need permission to access the member
  203. try {
  204. AccessController.doPrivileged(new PrivilegedExceptionAction() {
  205. public Object run() throws NoSuchMethodException {
  206. Class[] cl = new Class[2];
  207. cl[0] = SocketAddress.class;
  208. cl[1] = Integer.TYPE;
  209. impl.getClass().getDeclaredMethod("connect", cl);
  210. return null;
  211. }
  212. });
  213. } catch (java.security.PrivilegedActionException e) {
  214. oldImpl = true;
  215. }
  216. }
  217. private void setImpl() {
  218. if (factory != null) {
  219. impl = factory.createSocketImpl();
  220. checkOldImpl();
  221. } else {
  222. // No need to do a checkOldImpl() here, we know it's an up to date
  223. // SocketImpl!
  224. impl = new PlainSocketImpl();
  225. }
  226. if (impl != null)
  227. impl.setServerSocket(this);
  228. }
  229. /**
  230. * Creates the socket implementation.
  231. *
  232. * @throws IOException if creation fails
  233. * @since 1.4
  234. */
  235. void createImpl() throws SocketException {
  236. setImpl();
  237. try {
  238. impl.create(true);
  239. created = true;
  240. } catch (IOException e) {
  241. throw new SocketException(e.getMessage());
  242. }
  243. }
  244. /**
  245. *
  246. * Binds the <code>ServerSocket</code> to a specific address
  247. * (IP address and port number).
  248. * <p>
  249. * If the address is <code>null</code>, then the system will pick up
  250. * an ephemeral port and a valid local address to bind the socket.
  251. * <p>
  252. * @param endpoint The IP address & port number to bind to.
  253. * @throws IOException if the bind operation fails, or if the socket
  254. * is already bound.
  255. * @throws SecurityException if a <code>SecurityManager</code> is present and
  256. * its <code>checkListen</code> method doesn't allow the operation.
  257. * @throws IllegalArgumentException if endpoint is a
  258. * SocketAddress subclass not supported by this socket
  259. * @since 1.4
  260. */
  261. public void bind(SocketAddress endpoint) throws IOException {
  262. bind(endpoint, 50);
  263. }
  264. /**
  265. *
  266. * Binds the <code>ServerSocket</code> to a specific address
  267. * (IP address and port number).
  268. * <p>
  269. * If the address is <code>null</code>, then the system will pick up
  270. * an ephemeral port and a valid local address to bind the socket.
  271. * <P>
  272. * The <code>backlog</code> argument must be a positive
  273. * value greater than 0. If the value passed if equal or less
  274. * than 0, then the default value will be assumed.
  275. * @param endpoint The IP address & port number to bind to.
  276. * @param backlog The listen backlog length.
  277. * @throws IOException if the bind operation fails, or if the socket
  278. * is already bound.
  279. * @throws SecurityException if a <code>SecurityManager</code> is present and
  280. * its <code>checkListen</code> method doesn't allow the operation.
  281. * @throws IllegalArgumentException if endpoint is a
  282. * SocketAddress subclass not supported by this socket
  283. * @since 1.4
  284. */
  285. public void bind(SocketAddress endpoint, int backlog) throws IOException {
  286. if (isClosed())
  287. throw new SocketException("Socket is closed");
  288. if (!oldImpl && isBound())
  289. throw new SocketException("Already bound");
  290. if (endpoint == null)
  291. endpoint = new InetSocketAddress(0);
  292. if (!(endpoint instanceof InetSocketAddress))
  293. throw new IllegalArgumentException("Unsupported address type");
  294. InetSocketAddress epoint = (InetSocketAddress) endpoint;
  295. if (epoint.isUnresolved())
  296. throw new SocketException("Unresolved address");
  297. if (backlog < 1)
  298. backlog = 50;
  299. try {
  300. SecurityManager security = System.getSecurityManager();
  301. if (security != null)
  302. security.checkListen(epoint.getPort());
  303. getImpl().bind(epoint.getAddress(), epoint.getPort());
  304. getImpl().listen(backlog);
  305. bound = true;
  306. } catch(SecurityException e) {
  307. bound = false;
  308. throw e;
  309. } catch(IOException e) {
  310. bound = false;
  311. throw e;
  312. }
  313. }
  314. /**
  315. * Returns the local address of this server socket.
  316. *
  317. * @return the address to which this socket is bound,
  318. * or <code>null</code> if the socket is unbound.
  319. */
  320. public InetAddress getInetAddress() {
  321. if (!isBound())
  322. return null;
  323. try {
  324. return getImpl().getInetAddress();
  325. } catch (SocketException e) {
  326. // nothing
  327. // If we're bound, the the impl has been created
  328. // so we shouldn't get here
  329. }
  330. return null;
  331. }
  332. /**
  333. * Returns the port on which this socket is listening.
  334. *
  335. * @return the port number to which this socket is listening or
  336. * -1 if the socket is not bound yet.
  337. */
  338. public int getLocalPort() {
  339. if (!isBound())
  340. return -1;
  341. try {
  342. return getImpl().getLocalPort();
  343. } catch (SocketException e) {
  344. // nothing
  345. // If we're bound, the the impl has been created
  346. // so we shouldn't get here
  347. }
  348. return -1;
  349. }
  350. /**
  351. * Returns the address of the endpoint this socket is bound to, or
  352. * <code>null</code> if it is not bound yet.
  353. *
  354. * @return a <code>SocketAddress</code> representing the local endpoint of this
  355. * socket, or <code>null</code> if it is not bound yet.
  356. * @see #getInetAddress()
  357. * @see #getLocalPort()
  358. * @see #bind(SocketAddress)
  359. * @since 1.4
  360. */
  361. public SocketAddress getLocalSocketAddress() {
  362. if (!isBound())
  363. return null;
  364. return new InetSocketAddress(getInetAddress(), getLocalPort());
  365. }
  366. /**
  367. * Listens for a connection to be made to this socket and accepts
  368. * it. The method blocks until a connection is made.
  369. *
  370. * <p>A new Socket <code>s</code> is created and, if there
  371. * is a security manager,
  372. * the security manager's <code>checkAccept</code> method is called
  373. * with <code>s.getInetAddress().getHostAddress()</code> and
  374. * <code>s.getPort()</code>
  375. * as its arguments to ensure the operation is allowed.
  376. * This could result in a SecurityException.
  377. *
  378. * @exception IOException if an I/O error occurs when waiting for a
  379. * connection.
  380. * @exception SecurityException if a security manager exists and its
  381. * <code>checkListen</code> method doesn't allow the operation.
  382. * @exception SocketTimeoutException if a timeout was previously set with setSoTimeout and
  383. * the timeout has been reached.
  384. * @exception java.nio.channels.IllegalBlockingModeException
  385. * if this socket has an associated channel,
  386. * and the channel is in non-blocking mode.
  387. *
  388. * @return the new Socket
  389. * @see SecurityManager#checkAccept
  390. * @revised 1.4
  391. * @spec JSR-51
  392. */
  393. public Socket accept() throws IOException {
  394. if (isClosed())
  395. throw new SocketException("Socket is closed");
  396. if (!isBound())
  397. throw new SocketException("Socket is not bound yet");
  398. Socket s = new Socket((SocketImpl) null);
  399. implAccept(s);
  400. return s;
  401. }
  402. /**
  403. * Subclasses of ServerSocket use this method to override accept()
  404. * to return their own subclass of socket. So a FooServerSocket
  405. * will typically hand this method an <i>empty</i> FooSocket. On
  406. * return from implAccept the FooSocket will be connected to a client.
  407. *
  408. * @param s the Socket
  409. * @throws java.nio.channels.IllegalBlockingModeException
  410. * if this socket has an associated channel,
  411. * and the channel is in non-blocking mode
  412. * @throws IOException if an I/O error occurs when waiting
  413. * for a connection.
  414. * @since JDK1.1
  415. * @revised 1.4
  416. * @spec JSR-51
  417. */
  418. protected final void implAccept(Socket s) throws IOException {
  419. SocketImpl si = null;
  420. try {
  421. if (s.impl == null)
  422. s.setImpl();
  423. si = s.impl;
  424. s.impl = null;
  425. si.address = new InetAddress();
  426. si.fd = new FileDescriptor();
  427. getImpl().accept(si);
  428. SecurityManager security = System.getSecurityManager();
  429. if (security != null) {
  430. security.checkAccept(si.getInetAddress().getHostAddress(),
  431. si.getPort());
  432. }
  433. } catch (IOException e) {
  434. if (si != null)
  435. si.reset();
  436. s.impl = si;
  437. throw e;
  438. } catch (SecurityException e) {
  439. if (si != null)
  440. si.reset();
  441. s.impl = si;
  442. throw e;
  443. }
  444. s.impl = si;
  445. s.postAccept();
  446. }
  447. /**
  448. * Closes this socket.
  449. *
  450. * Any thread currently blocked in {@link #accept()} will throw
  451. * a {@link SocketException}.
  452. *
  453. * <p> If this socket has an associated channel then the channel is closed
  454. * as well.
  455. *
  456. * @exception IOException if an I/O error occurs when closing the socket.
  457. * @revised 1.4
  458. * @spec JSR-51
  459. */
  460. public void close() throws IOException {
  461. synchronized(closeLock) {
  462. if (isClosed())
  463. return;
  464. if (created)
  465. impl.close();
  466. closed = true;
  467. }
  468. }
  469. /**
  470. * Returns the unique {@link java.nio.channels.ServerSocketChannel} object
  471. * associated with this socket, if any.
  472. *
  473. * <p> A server socket will have a channel if, and only if, the channel
  474. * itself was created via the {@link
  475. * java.nio.channels.ServerSocketChannel#open ServerSocketChannel.open}
  476. * method.
  477. *
  478. * @return the server-socket channel associated with this socket,
  479. * or <tt>null</tt> if this socket was not created
  480. * for a channel
  481. *
  482. * @since 1.4
  483. * @spec JSR-51
  484. */
  485. public ServerSocketChannel getChannel() {
  486. return null;
  487. }
  488. /**
  489. * Returns the binding state of the ServerSocket.
  490. *
  491. * @return true if the ServerSocket succesfuly bound to an address
  492. * @since 1.4
  493. */
  494. public boolean isBound() {
  495. // Before 1.3 ServerSockets were always bound during creation
  496. return bound || oldImpl;
  497. }
  498. /**
  499. * Returns the closed state of the ServerSocket.
  500. *
  501. * @return true if the socket has been closed
  502. * @since 1.4
  503. */
  504. public boolean isClosed() {
  505. synchronized(closeLock) {
  506. return closed;
  507. }
  508. }
  509. /**
  510. * Enable/disable SO_TIMEOUT with the specified timeout, in
  511. * milliseconds. With this option set to a non-zero timeout,
  512. * a call to accept() for this ServerSocket
  513. * will block for only this amount of time. If the timeout expires,
  514. * a <B>java.net.SocketTimeoutException</B> is raised, though the
  515. * ServerSocket is still valid. The option <B>must</B> be enabled
  516. * prior to entering the blocking operation to have effect. The
  517. * timeout must be > 0.
  518. * A timeout of zero is interpreted as an infinite timeout.
  519. * @param timeout the specified timeout, in milliseconds
  520. * @exception SocketException if there is an error in
  521. * the underlying protocol, such as a TCP error.
  522. * @since JDK1.1
  523. * @see #getSoTimeout()
  524. */
  525. public synchronized void setSoTimeout(int timeout) throws SocketException {
  526. if (isClosed())
  527. throw new SocketException("Socket is closed");
  528. getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
  529. }
  530. /**
  531. * Retrive setting for SO_TIMEOUT. 0 returns implies that the
  532. * option is disabled (i.e., timeout of infinity).
  533. * @return the SO_TIMEOUT value
  534. * @exception IOException if an I/O error occurs
  535. * @since JDK1.1
  536. * @see #setSoTimeout(int)
  537. */
  538. public synchronized int getSoTimeout() throws IOException {
  539. if (isClosed())
  540. throw new SocketException("Socket is closed");
  541. Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
  542. /* extra type safety */
  543. if (o instanceof Integer) {
  544. return ((Integer) o).intValue();
  545. } else {
  546. return 0;
  547. }
  548. }
  549. /**
  550. * Enable/disable the SO_REUSEADDR socket option.
  551. * <p>
  552. * When a TCP connection is closed the connection may remain
  553. * in a timeout state for a period of time after the connection
  554. * is closed (typically known as the <tt>TIME_WAIT</tt> state
  555. * or <tt>2MSL</tt> wait state).
  556. * For applications using a well known socket address or port
  557. * it may not be possible to bind a socket to the required
  558. * <tt>SocketAddress</tt> if there is a connection in the
  559. * timeout state involving the socket address or port.
  560. * <p>
  561. * Enabling <tt>SO_REUSEADDR</tt> prior to binding the socket
  562. * using {@link #bind(SocketAddress)} allows the socket to be
  563. * bound even though a previous connection is in a timeout
  564. * state.
  565. * <p>
  566. * When a <tt>ServerSocket</tt> is created the initial setting
  567. * of <tt>SO_REUSEADDR</tt> is not defined. Applications can
  568. * use {@link getReuseAddress()} to determine the initial
  569. * setting of <tt>SO_REUSEADDR</tt>.
  570. * <p>
  571. * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
  572. * disabled after a socket is bound (See {@link #isBound()})
  573. * is not defined.
  574. *
  575. * @param on whether to enable or disable the socket option
  576. * @exception SocketException if an error occurs enabling or
  577. * disabling the <tt>SO_RESUEADDR</tt> socket option,
  578. * or the socket is closed.
  579. * @since 1.4
  580. * @see #getReuseAddress()
  581. * @see #bind(SocketAddress)
  582. * @see #isBound()
  583. * @see #isClosed()
  584. */
  585. public void setReuseAddress(boolean on) throws SocketException {
  586. if (isClosed())
  587. throw new SocketException("Socket is closed");
  588. getImpl().setOption(SocketOptions.SO_REUSEADDR, new Boolean(on));
  589. }
  590. /**
  591. * Tests if SO_REUSEADDR is enabled.
  592. *
  593. * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
  594. * @exception SocketException if there is an error
  595. * in the underlying protocol, such as a TCP error.
  596. * @since 1.4
  597. * @see #setReuseAddress(boolean)
  598. */
  599. public boolean getReuseAddress() throws SocketException {
  600. if (isClosed())
  601. throw new SocketException("Socket is closed");
  602. return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
  603. }
  604. /**
  605. * Returns the implementation address and implementation port of
  606. * this socket as a <code>String</code>.
  607. *
  608. * @return a string representation of this socket.
  609. */
  610. public String toString() {
  611. if (!isBound())
  612. return "ServerSocket[unbound]";
  613. return "ServerSocket[addr=" + impl.getInetAddress() +
  614. ",port=" + impl.getPort() +
  615. ",localport=" + impl.getLocalPort() + "]";
  616. }
  617. void setBound() {
  618. bound = true;
  619. }
  620. void setCreated() {
  621. created = true;
  622. }
  623. /**
  624. * The factory for all server sockets.
  625. */
  626. private static SocketImplFactory factory;
  627. /**
  628. * Sets the server socket implementation factory for the
  629. * application. The factory can be specified only once.
  630. * <p>
  631. * When an application creates a new server socket, the socket
  632. * implementation factory's <code>createSocketImpl</code> method is
  633. * called to create the actual socket implementation.
  634. * <p>
  635. * If there is a security manager, this method first calls
  636. * the security manager's <code>checkSetFactory</code> method
  637. * to ensure the operation is allowed.
  638. * This could result in a SecurityException.
  639. *
  640. * @param fac the desired factory.
  641. * @exception IOException if an I/O error occurs when setting the
  642. * socket factory.
  643. * @exception SocketException if the factory has already been defined.
  644. * @exception SecurityException if a security manager exists and its
  645. * <code>checkSetFactory</code> method doesn't allow the operation.
  646. * @see java.net.SocketImplFactory#createSocketImpl()
  647. * @see SecurityManager#checkSetFactory
  648. */
  649. public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException {
  650. if (factory != null) {
  651. throw new SocketException("factory already defined");
  652. }
  653. SecurityManager security = System.getSecurityManager();
  654. if (security != null) {
  655. security.checkSetFactory();
  656. }
  657. factory = fac;
  658. }
  659. /**
  660. * Sets a default proposed value for the SO_RCVBUF option for sockets
  661. * accepted from this <tt>ServerSocket</tt>. The value actually set
  662. * in the accepted socket must be determined by calling
  663. * {@link Socket#getReceiveBufferSize()} after the socket
  664. * is returned by {@link #accept()}.
  665. * <p>
  666. * The value of SO_RCVBUF is used both to set the size of the internal
  667. * socket receive buffer, and to set the size of the TCP receive window
  668. * that is advertized to the remote peer.
  669. * <p>
  670. * It is possible to change the value subsequently, by calling
  671. * {@link Socket#setReceiveBufferSize(int)}. However, if the application
  672. * wishes to allow a receive window larger than 64K bytes, as defined by RFC1323
  673. * then the proposed value must be set in the ServerSocket <B>before</B>
  674. * it is bound to a local address. This implies, that the ServerSocket must be
  675. * created with the no-argument constructor, then setReceiveBufferSize() must
  676. * be called and lastly the ServerSocket is bound to an address by calling bind().
  677. * <p>
  678. * Failure to do this will not cause an error, and the buffer size may be set to the
  679. * requested value but the TCP receive window in sockets accepted from
  680. * this ServerSocket will be no larger than 64K bytes.
  681. *
  682. * @exception SocketException if there is an error
  683. * in the underlying protocol, such as a TCP error.
  684. *
  685. * @param size the size to which to set the receive buffer
  686. * size. This value must be greater than 0.
  687. *
  688. * @exception IllegalArgumentException if the
  689. * value is 0 or is negative.
  690. *
  691. * @since 1.4
  692. * @see #getReceiveBufferSize
  693. */
  694. public synchronized void setReceiveBufferSize (int size) throws SocketException {
  695. if (!(size > 0)) {
  696. throw new IllegalArgumentException("negative receive size");
  697. }
  698. if (isClosed())
  699. throw new SocketException("Socket is closed");
  700. getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
  701. }
  702. /**
  703. * Gets the value of the SO_RCVBUF option for this <tt>ServerSocket</tt>,
  704. * that is the proposed buffer size that will be used for Sockets accepted
  705. * from this <tt>ServerSocket</tt>.
  706. *
  707. * <p>Note, the value actually set in the accepted socket is determined by
  708. * calling {@link Socket#getReceiveBufferSize()}.
  709. * @return the value of the SO_RCVBUF option for this <tt>Socket</tt>.
  710. * @exception SocketException if there is an error
  711. * in the underlying protocol, such as a TCP error.
  712. * @see #setReceiveBufferSize(int)
  713. * @since 1.4
  714. */
  715. public synchronized int getReceiveBufferSize()
  716. throws SocketException{
  717. if (isClosed())
  718. throw new SocketException("Socket is closed");
  719. int result = 0;
  720. Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
  721. if (o instanceof Integer) {
  722. result = ((Integer)o).intValue();
  723. }
  724. return result;
  725. }
  726. }