1. /*
  2. * @(#)ServerSocket.java 1.86 04/05/24
  3. *
  4. * Copyright 2004 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.86, 05/24/04
  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 SocksSocketImpl();
  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. if (impl == null)
  237. setImpl();
  238. try {
  239. impl.create(true);
  240. created = true;
  241. } catch (IOException e) {
  242. throw new SocketException(e.getMessage());
  243. }
  244. }
  245. /**
  246. *
  247. * Binds the <code>ServerSocket</code> to a specific address
  248. * (IP address and port number).
  249. * <p>
  250. * If the address is <code>null</code>, then the system will pick up
  251. * an ephemeral port and a valid local address to bind the socket.
  252. * <p>
  253. * @param endpoint The IP address & port number to bind to.
  254. * @throws IOException if the bind operation fails, or if the socket
  255. * is already bound.
  256. * @throws SecurityException if a <code>SecurityManager</code> is present and
  257. * its <code>checkListen</code> method doesn't allow the operation.
  258. * @throws IllegalArgumentException if endpoint is a
  259. * SocketAddress subclass not supported by this socket
  260. * @since 1.4
  261. */
  262. public void bind(SocketAddress endpoint) throws IOException {
  263. bind(endpoint, 50);
  264. }
  265. /**
  266. *
  267. * Binds the <code>ServerSocket</code> to a specific address
  268. * (IP address and port number).
  269. * <p>
  270. * If the address is <code>null</code>, then the system will pick up
  271. * an ephemeral port and a valid local address to bind the socket.
  272. * <P>
  273. * The <code>backlog</code> argument must be a positive
  274. * value greater than 0. If the value passed if equal or less
  275. * than 0, then the default value will be assumed.
  276. * @param endpoint The IP address & port number to bind to.
  277. * @param backlog The listen backlog length.
  278. * @throws IOException if the bind operation fails, or if the socket
  279. * is already bound.
  280. * @throws SecurityException if a <code>SecurityManager</code> is present and
  281. * its <code>checkListen</code> method doesn't allow the operation.
  282. * @throws IllegalArgumentException if endpoint is a
  283. * SocketAddress subclass not supported by this socket
  284. * @since 1.4
  285. */
  286. public void bind(SocketAddress endpoint, int backlog) throws IOException {
  287. if (isClosed())
  288. throw new SocketException("Socket is closed");
  289. if (!oldImpl && isBound())
  290. throw new SocketException("Already bound");
  291. if (endpoint == null)
  292. endpoint = new InetSocketAddress(0);
  293. if (!(endpoint instanceof InetSocketAddress))
  294. throw new IllegalArgumentException("Unsupported address type");
  295. InetSocketAddress epoint = (InetSocketAddress) endpoint;
  296. if (epoint.isUnresolved())
  297. throw new SocketException("Unresolved address");
  298. if (backlog < 1)
  299. backlog = 50;
  300. try {
  301. SecurityManager security = System.getSecurityManager();
  302. if (security != null)
  303. security.checkListen(epoint.getPort());
  304. getImpl().bind(epoint.getAddress(), epoint.getPort());
  305. getImpl().listen(backlog);
  306. bound = true;
  307. } catch(SecurityException e) {
  308. bound = false;
  309. throw e;
  310. } catch(IOException e) {
  311. bound = false;
  312. throw e;
  313. }
  314. }
  315. /**
  316. * Returns the local address of this server socket.
  317. *
  318. * @return the address to which this socket is bound,
  319. * or <code>null</code> if the socket is unbound.
  320. */
  321. public InetAddress getInetAddress() {
  322. if (!isBound())
  323. return null;
  324. try {
  325. return getImpl().getInetAddress();
  326. } catch (SocketException e) {
  327. // nothing
  328. // If we're bound, the the impl has been created
  329. // so we shouldn't get here
  330. }
  331. return null;
  332. }
  333. /**
  334. * Returns the port on which this socket is listening.
  335. *
  336. * @return the port number to which this socket is listening or
  337. * -1 if the socket is not bound yet.
  338. */
  339. public int getLocalPort() {
  340. if (!isBound())
  341. return -1;
  342. try {
  343. return getImpl().getLocalPort();
  344. } catch (SocketException e) {
  345. // nothing
  346. // If we're bound, the the impl has been created
  347. // so we shouldn't get here
  348. }
  349. return -1;
  350. }
  351. /**
  352. * Returns the address of the endpoint this socket is bound to, or
  353. * <code>null</code> if it is not bound yet.
  354. *
  355. * @return a <code>SocketAddress</code> representing the local endpoint of this
  356. * socket, or <code>null</code> if it is not bound yet.
  357. * @see #getInetAddress()
  358. * @see #getLocalPort()
  359. * @see #bind(SocketAddress)
  360. * @since 1.4
  361. */
  362. public SocketAddress getLocalSocketAddress() {
  363. if (!isBound())
  364. return null;
  365. return new InetSocketAddress(getInetAddress(), getLocalPort());
  366. }
  367. /**
  368. * Listens for a connection to be made to this socket and accepts
  369. * it. The method blocks until a connection is made.
  370. *
  371. * <p>A new Socket <code>s</code> is created and, if there
  372. * is a security manager,
  373. * the security manager's <code>checkAccept</code> method is called
  374. * with <code>s.getInetAddress().getHostAddress()</code> and
  375. * <code>s.getPort()</code>
  376. * as its arguments to ensure the operation is allowed.
  377. * This could result in a SecurityException.
  378. *
  379. * @exception IOException if an I/O error occurs when waiting for a
  380. * connection.
  381. * @exception SecurityException if a security manager exists and its
  382. * <code>checkListen</code> method doesn't allow the operation.
  383. * @exception SocketTimeoutException if a timeout was previously set with setSoTimeout and
  384. * the timeout has been reached.
  385. * @exception java.nio.channels.IllegalBlockingModeException
  386. * if this socket has an associated channel, the channel is in
  387. * non-blocking mode, and there is no connection ready to be
  388. * accepted
  389. *
  390. * @return the new Socket
  391. * @see SecurityManager#checkAccept
  392. * @revised 1.4
  393. * @spec JSR-51
  394. */
  395. public Socket accept() throws IOException {
  396. if (isClosed())
  397. throw new SocketException("Socket is closed");
  398. if (!isBound())
  399. throw new SocketException("Socket is not bound yet");
  400. Socket s = new Socket((SocketImpl) null);
  401. implAccept(s);
  402. return s;
  403. }
  404. /**
  405. * Subclasses of ServerSocket use this method to override accept()
  406. * to return their own subclass of socket. So a FooServerSocket
  407. * will typically hand this method an <i>empty</i> FooSocket. On
  408. * return from implAccept the FooSocket will be connected to a client.
  409. *
  410. * @param s the Socket
  411. * @throws java.nio.channels.IllegalBlockingModeException
  412. * if this socket has an associated channel,
  413. * and the channel is in non-blocking mode
  414. * @throws IOException if an I/O error occurs when waiting
  415. * for a connection.
  416. * @since JDK1.1
  417. * @revised 1.4
  418. * @spec JSR-51
  419. */
  420. protected final void implAccept(Socket s) throws IOException {
  421. SocketImpl si = null;
  422. try {
  423. if (s.impl == null)
  424. s.setImpl();
  425. si = s.impl;
  426. s.impl = null;
  427. si.address = new InetAddress();
  428. si.fd = new FileDescriptor();
  429. getImpl().accept(si);
  430. SecurityManager security = System.getSecurityManager();
  431. if (security != null) {
  432. security.checkAccept(si.getInetAddress().getHostAddress(),
  433. si.getPort());
  434. }
  435. } catch (IOException e) {
  436. if (si != null)
  437. si.reset();
  438. s.impl = si;
  439. throw e;
  440. } catch (SecurityException e) {
  441. if (si != null)
  442. si.reset();
  443. s.impl = si;
  444. throw e;
  445. }
  446. s.impl = si;
  447. s.postAccept();
  448. }
  449. /**
  450. * Closes this socket.
  451. *
  452. * Any thread currently blocked in {@link #accept()} will throw
  453. * a {@link SocketException}.
  454. *
  455. * <p> If this socket has an associated channel then the channel is closed
  456. * as well.
  457. *
  458. * @exception IOException if an I/O error occurs when closing the socket.
  459. * @revised 1.4
  460. * @spec JSR-51
  461. */
  462. public void close() throws IOException {
  463. synchronized(closeLock) {
  464. if (isClosed())
  465. return;
  466. if (created)
  467. impl.close();
  468. closed = true;
  469. }
  470. }
  471. /**
  472. * Returns the unique {@link java.nio.channels.ServerSocketChannel} object
  473. * associated with this socket, if any.
  474. *
  475. * <p> A server socket will have a channel if, and only if, the channel
  476. * itself was created via the {@link
  477. * java.nio.channels.ServerSocketChannel#open ServerSocketChannel.open}
  478. * method.
  479. *
  480. * @return the server-socket channel associated with this socket,
  481. * or <tt>null</tt> if this socket was not created
  482. * for a channel
  483. *
  484. * @since 1.4
  485. * @spec JSR-51
  486. */
  487. public ServerSocketChannel getChannel() {
  488. return null;
  489. }
  490. /**
  491. * Returns the binding state of the ServerSocket.
  492. *
  493. * @return true if the ServerSocket succesfuly bound to an address
  494. * @since 1.4
  495. */
  496. public boolean isBound() {
  497. // Before 1.3 ServerSockets were always bound during creation
  498. return bound || oldImpl;
  499. }
  500. /**
  501. * Returns the closed state of the ServerSocket.
  502. *
  503. * @return true if the socket has been closed
  504. * @since 1.4
  505. */
  506. public boolean isClosed() {
  507. synchronized(closeLock) {
  508. return closed;
  509. }
  510. }
  511. /**
  512. * Enable/disable SO_TIMEOUT with the specified timeout, in
  513. * milliseconds. With this option set to a non-zero timeout,
  514. * a call to accept() for this ServerSocket
  515. * will block for only this amount of time. If the timeout expires,
  516. * a <B>java.net.SocketTimeoutException</B> is raised, though the
  517. * ServerSocket is still valid. The option <B>must</B> be enabled
  518. * prior to entering the blocking operation to have effect. The
  519. * timeout must be > 0.
  520. * A timeout of zero is interpreted as an infinite timeout.
  521. * @param timeout the specified timeout, in milliseconds
  522. * @exception SocketException if there is an error in
  523. * the underlying protocol, such as a TCP error.
  524. * @since JDK1.1
  525. * @see #getSoTimeout()
  526. */
  527. public synchronized void setSoTimeout(int timeout) throws SocketException {
  528. if (isClosed())
  529. throw new SocketException("Socket is closed");
  530. getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
  531. }
  532. /**
  533. * Retrive setting for SO_TIMEOUT. 0 returns implies that the
  534. * option is disabled (i.e., timeout of infinity).
  535. * @return the SO_TIMEOUT value
  536. * @exception IOException if an I/O error occurs
  537. * @since JDK1.1
  538. * @see #setSoTimeout(int)
  539. */
  540. public synchronized int getSoTimeout() throws IOException {
  541. if (isClosed())
  542. throw new SocketException("Socket is closed");
  543. Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
  544. /* extra type safety */
  545. if (o instanceof Integer) {
  546. return ((Integer) o).intValue();
  547. } else {
  548. return 0;
  549. }
  550. }
  551. /**
  552. * Enable/disable the SO_REUSEADDR socket option.
  553. * <p>
  554. * When a TCP connection is closed the connection may remain
  555. * in a timeout state for a period of time after the connection
  556. * is closed (typically known as the <tt>TIME_WAIT</tt> state
  557. * or <tt>2MSL</tt> wait state).
  558. * For applications using a well known socket address or port
  559. * it may not be possible to bind a socket to the required
  560. * <tt>SocketAddress</tt> if there is a connection in the
  561. * timeout state involving the socket address or port.
  562. * <p>
  563. * Enabling <tt>SO_REUSEADDR</tt> prior to binding the socket
  564. * using {@link #bind(SocketAddress)} allows the socket to be
  565. * bound even though a previous connection is in a timeout
  566. * state.
  567. * <p>
  568. * When a <tt>ServerSocket</tt> is created the initial setting
  569. * of <tt>SO_REUSEADDR</tt> is not defined. Applications can
  570. * use {@link #getReuseAddress()} to determine the initial
  571. * setting of <tt>SO_REUSEADDR</tt>.
  572. * <p>
  573. * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
  574. * disabled after a socket is bound (See {@link #isBound()})
  575. * is not defined.
  576. *
  577. * @param on whether to enable or disable the socket option
  578. * @exception SocketException if an error occurs enabling or
  579. * disabling the <tt>SO_RESUEADDR</tt> socket option,
  580. * or the socket is closed.
  581. * @since 1.4
  582. * @see #getReuseAddress()
  583. * @see #bind(SocketAddress)
  584. * @see #isBound()
  585. * @see #isClosed()
  586. */
  587. public void setReuseAddress(boolean on) throws SocketException {
  588. if (isClosed())
  589. throw new SocketException("Socket is closed");
  590. getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
  591. }
  592. /**
  593. * Tests if SO_REUSEADDR is enabled.
  594. *
  595. * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
  596. * @exception SocketException if there is an error
  597. * in the underlying protocol, such as a TCP error.
  598. * @since 1.4
  599. * @see #setReuseAddress(boolean)
  600. */
  601. public boolean getReuseAddress() throws SocketException {
  602. if (isClosed())
  603. throw new SocketException("Socket is closed");
  604. return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
  605. }
  606. /**
  607. * Returns the implementation address and implementation port of
  608. * this socket as a <code>String</code>.
  609. *
  610. * @return a string representation of this socket.
  611. */
  612. public String toString() {
  613. if (!isBound())
  614. return "ServerSocket[unbound]";
  615. return "ServerSocket[addr=" + impl.getInetAddress() +
  616. ",port=" + impl.getPort() +
  617. ",localport=" + impl.getLocalPort() + "]";
  618. }
  619. void setBound() {
  620. bound = true;
  621. }
  622. void setCreated() {
  623. created = true;
  624. }
  625. /**
  626. * The factory for all server sockets.
  627. */
  628. private static SocketImplFactory factory = null;
  629. /**
  630. * Sets the server socket implementation factory for the
  631. * application. The factory can be specified only once.
  632. * <p>
  633. * When an application creates a new server socket, the socket
  634. * implementation factory's <code>createSocketImpl</code> method is
  635. * called to create the actual socket implementation.
  636. * <p>
  637. * Passing <code>null</code> to the method is a no-op unless the factory
  638. * was already set.
  639. * <p>
  640. * If there is a security manager, this method first calls
  641. * the security manager's <code>checkSetFactory</code> method
  642. * to ensure the operation is allowed.
  643. * This could result in a SecurityException.
  644. *
  645. * @param fac the desired factory.
  646. * @exception IOException if an I/O error occurs when setting the
  647. * socket factory.
  648. * @exception SocketException if the factory has already been defined.
  649. * @exception SecurityException if a security manager exists and its
  650. * <code>checkSetFactory</code> method doesn't allow the operation.
  651. * @see java.net.SocketImplFactory#createSocketImpl()
  652. * @see SecurityManager#checkSetFactory
  653. */
  654. public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException {
  655. if (factory != null) {
  656. throw new SocketException("factory already defined");
  657. }
  658. SecurityManager security = System.getSecurityManager();
  659. if (security != null) {
  660. security.checkSetFactory();
  661. }
  662. factory = fac;
  663. }
  664. /**
  665. * Sets a default proposed value for the SO_RCVBUF option for sockets
  666. * accepted from this <tt>ServerSocket</tt>. The value actually set
  667. * in the accepted socket must be determined by calling
  668. * {@link Socket#getReceiveBufferSize()} after the socket
  669. * is returned by {@link #accept()}.
  670. * <p>
  671. * The value of SO_RCVBUF is used both to set the size of the internal
  672. * socket receive buffer, and to set the size of the TCP receive window
  673. * that is advertized to the remote peer.
  674. * <p>
  675. * It is possible to change the value subsequently, by calling
  676. * {@link Socket#setReceiveBufferSize(int)}. However, if the application
  677. * wishes to allow a receive window larger than 64K bytes, as defined by RFC1323
  678. * then the proposed value must be set in the ServerSocket <B>before</B>
  679. * it is bound to a local address. This implies, that the ServerSocket must be
  680. * created with the no-argument constructor, then setReceiveBufferSize() must
  681. * be called and lastly the ServerSocket is bound to an address by calling bind().
  682. * <p>
  683. * Failure to do this will not cause an error, and the buffer size may be set to the
  684. * requested value but the TCP receive window in sockets accepted from
  685. * this ServerSocket will be no larger than 64K bytes.
  686. *
  687. * @exception SocketException if there is an error
  688. * in the underlying protocol, such as a TCP error.
  689. *
  690. * @param size the size to which to set the receive buffer
  691. * size. This value must be greater than 0.
  692. *
  693. * @exception IllegalArgumentException if the
  694. * value is 0 or is negative.
  695. *
  696. * @since 1.4
  697. * @see #getReceiveBufferSize
  698. */
  699. public synchronized void setReceiveBufferSize (int size) throws SocketException {
  700. if (!(size > 0)) {
  701. throw new IllegalArgumentException("negative receive size");
  702. }
  703. if (isClosed())
  704. throw new SocketException("Socket is closed");
  705. getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
  706. }
  707. /**
  708. * Gets the value of the SO_RCVBUF option for this <tt>ServerSocket</tt>,
  709. * that is the proposed buffer size that will be used for Sockets accepted
  710. * from this <tt>ServerSocket</tt>.
  711. *
  712. * <p>Note, the value actually set in the accepted socket is determined by
  713. * calling {@link Socket#getReceiveBufferSize()}.
  714. * @return the value of the SO_RCVBUF option for this <tt>Socket</tt>.
  715. * @exception SocketException if there is an error
  716. * in the underlying protocol, such as a TCP error.
  717. * @see #setReceiveBufferSize(int)
  718. * @since 1.4
  719. */
  720. public synchronized int getReceiveBufferSize()
  721. throws SocketException{
  722. if (isClosed())
  723. throw new SocketException("Socket is closed");
  724. int result = 0;
  725. Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
  726. if (o instanceof Integer) {
  727. result = ((Integer)o).intValue();
  728. }
  729. return result;
  730. }
  731. /**
  732. * Sets performance preferences for this ServerSocket.
  733. *
  734. * <p> Sockets use the TCP/IP protocol by default. Some implementations
  735. * may offer alternative protocols which have different performance
  736. * characteristics than TCP/IP. This method allows the application to
  737. * express its own preferences as to how these tradeoffs should be made
  738. * when the implementation chooses from the available protocols.
  739. *
  740. * <p> Performance preferences are described by three integers
  741. * whose values indicate the relative importance of short connection time,
  742. * low latency, and high bandwidth. The absolute values of the integers
  743. * are irrelevant; in order to choose a protocol the values are simply
  744. * compared, with larger values indicating stronger preferences. If the
  745. * application prefers short connection time over both low latency and high
  746. * bandwidth, for example, then it could invoke this method with the values
  747. * <tt>(1, 0, 0)</tt>. If the application prefers high bandwidth above low
  748. * latency, and low latency above short connection time, then it could
  749. * invoke this method with the values <tt>(0, 1, 2)</tt>.
  750. *
  751. * <p> Invoking this method after this socket has been bound
  752. * will have no effect. This implies that in order to use this capability
  753. * requires the socket to be created with the no-argument constructor.
  754. *
  755. * @param connectionTime
  756. * An <tt>int</tt> expressing the relative importance of a short
  757. * connection time
  758. *
  759. * @param latency
  760. * An <tt>int</tt> expressing the relative importance of low
  761. * latency
  762. *
  763. * @param bandwidth
  764. * An <tt>int</tt> expressing the relative importance of high
  765. * bandwidth
  766. *
  767. * @since 1.5
  768. */
  769. public void setPerformancePreferences(int connectionTime,
  770. int latency,
  771. int bandwidth)
  772. {
  773. /* Not implemented yet */
  774. }
  775. }