001: /*
002: * @(#)ServerSocket.java 1.51 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package java.net;
029:
030: import java.io.FileDescriptor;
031: import java.io.IOException;
032: import java.security.AccessController;
033: import java.security.PrivilegedExceptionAction;
034:
035: /**
036: * This class implements server sockets. A server socket waits for
037: * requests to come in over the network. It performs some operation
038: * based on that request, and then possibly returns a result to the requester.
039: * <p>
040: * The actual work of the server socket is performed by an instance
041: * of the <code>SocketImpl</code> class. An application can
042: * change the socket factory that creates the socket
043: * implementation to configure itself to create sockets
044: * appropriate to the local firewall.
045: *
046: * @author unascribed
047: * @version 1.43 10/17/00
048: * @see java.net.SocketImpl
049: * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
050: * @since JDK1.0
051: */
052: public class ServerSocket {
053: /**
054: * Various states of this socket.
055: */
056: private boolean created = false;
057: private boolean bound = false;
058: private boolean closed = false;
059: private Object closeLock = new Object();
060:
061: /**
062: * The implementation of this Socket.
063: */
064: private SocketImpl impl;
065:
066: /**
067: * Are we using an older SocketImpl?
068: */
069: private boolean oldImpl = false;
070:
071: /**
072: * Creates an unbound server socket.
073: *
074: * @exception IOException IO error when opening the socket.
075: * @revised 1.4
076: */
077: public ServerSocket() throws IOException {
078: setImpl();
079: }
080:
081: /**
082: * Creates a server socket, bound to the specified port. A port of
083: * <code>0</code> creates a socket on any free port.
084: * <p>
085: * The maximum queue length for incoming connection indications (a
086: * request to connect) is set to <code>50</code>. If a connection
087: * indication arrives when the queue is full, the connection is refused.
088: * <p>
089: * If the application has specified a server socket factory, that
090: * factory's <code>createSocketImpl</code> method is called to create
091: * the actual socket implementation. Otherwise a "plain" socket is created.
092: * <p>
093: * If there is a security manager,
094: * its <code>checkListen</code> method is called
095: * with the <code>port</code> argument
096: * as its argument to ensure the operation is allowed.
097: * This could result in a SecurityException.
098: *
099: *
100: * @param port the port number, or <code>0</code> to use any
101: * free port.
102: *
103: * @exception IOException if an I/O error occurs when opening the socket.
104: * @exception SecurityException
105: * if a security manager exists and its <code>checkListen</code>
106: * method doesn't allow the operation.
107: *
108: * @see java.net.SocketImpl
109: * @see java.net.SocketImplFactory#createSocketImpl()
110: * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
111: * @see SecurityManager#checkListen
112: */
113: public ServerSocket(int port) throws IOException {
114: this (port, 50, null);
115: }
116:
117: /**
118: * Creates a server socket and binds it to the specified local port
119: * number, with the specified backlog.
120: * A port number of <code>0</code> creates a socket on any
121: * free port.
122: * <p>
123: * The maximum queue length for incoming connection indications (a
124: * request to connect) is set to the <code>backlog</code> parameter. If
125: * a connection indication arrives when the queue is full, the
126: * connection is refused.
127: * <p>
128: * If the application has specified a server socket factory, that
129: * factory's <code>createSocketImpl</code> method is called to create
130: * the actual socket implementation. Otherwise a "plain" socket is created.
131: * <p>
132: * If there is a security manager,
133: * its <code>checkListen</code> method is called
134: * with the <code>port</code> argument
135: * as its argument to ensure the operation is allowed.
136: * This could result in a SecurityException.
137: *
138: * <P>The <code>backlog</code> argument must be a positive
139: * value greater than 0. If the value passed if equal or less
140: * than 0, then the default value will be assumed.
141: * <P>
142: *
143: * @param port the specified port, or <code>0</code> to use
144: * any free port.
145: * @param backlog the maximum length of the queue.
146: *
147: * @exception IOException if an I/O error occurs when opening the socket.
148: * @exception SecurityException
149: * if a security manager exists and its <code>checkListen</code>
150: * method doesn't allow the operation.
151: *
152: * @see java.net.SocketImpl
153: * @see java.net.SocketImplFactory#createSocketImpl()
154: * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
155: * @see SecurityManager#checkListen
156: */
157: public ServerSocket(int port, int backlog) throws IOException {
158: this (port, backlog, null);
159: }
160:
161: /**
162: * Create a server with the specified port, listen backlog, and
163: * local IP address to bind to. The <i>bindAddr</i> argument
164: * can be used on a multi-homed host for a ServerSocket that
165: * will only accept connect requests to one of its addresses.
166: * If <i>bindAddr</i> is null, it will default accepting
167: * connections on any/all local addresses.
168: * The port must be between 0 and 65535, inclusive.
169: *
170: * <P>If there is a security manager, this method
171: * calls its <code>checkListen</code> method
172: * with the <code>port</code> argument
173: * as its argument to ensure the operation is allowed.
174: * This could result in a SecurityException.
175: *
176: * <P>The <code>backlog</code> argument must be a positive
177: * value greater than 0. If the value passed if equal or less
178: * than 0, then the default value will be assumed.
179: * <P>
180: * @param port the local TCP port
181: * @param backlog the listen backlog
182: * @param bindAddr the local InetAddress the server will bind to
183: *
184: * @throws SecurityException if a security manager exists and
185: * its <code>checkListen</code> method doesn't allow the operation.
186: *
187: * @throws IOException if an I/O error occurs when opening the socket.
188: *
189: * @see SocketOptions
190: * @see SocketImpl
191: * @see SecurityManager#checkListen
192: * @since JDK1.1
193: */
194: public ServerSocket(int port, int backlog, InetAddress bindAddr)
195: throws IOException {
196: setImpl();
197: if (port < 0 || port > 0xFFFF)
198: throw new IllegalArgumentException(
199: "Port value out of range: " + port);
200: if (backlog < 1)
201: backlog = 50;
202: try {
203: bind(new InetSocketAddress(bindAddr, port), backlog);
204: } catch (SecurityException e) {
205: close();
206: throw e;
207: } catch (IOException e) {
208: close();
209: throw e;
210: }
211: }
212:
213: /**
214: * Get the <code>SocketImpl</code> attached to this socket, creating
215: * it if necessary.
216: *
217: * @return the <code>SocketImpl</code> attached to that ServerSocket.
218: * @throws SocketException if creation fails.
219: * @since 1.4
220: */
221: SocketImpl getImpl() throws SocketException {
222: if (!created)
223: createImpl();
224: return impl;
225: }
226:
227: private void checkOldImpl() {
228: if (impl == null)
229: return;
230: // SocketImpl.connect() is a protected method, therefore we need to use
231: // getDeclaredMethod, therefore we need permission to access the member
232: try {
233: AccessController
234: .doPrivileged(new PrivilegedExceptionAction() {
235: public Object run()
236: throws NoSuchMethodException {
237: Class[] cl = new Class[2];
238: cl[0] = SocketAddress.class;
239: cl[1] = Integer.TYPE;
240: impl.getClass().getDeclaredMethod(
241: "connect", cl);
242: return null;
243: }
244: });
245: } catch (java.security.PrivilegedActionException e) {
246: oldImpl = true;
247: }
248: }
249:
250: private void setImpl() {
251: if (factory != null) {
252: impl = factory.createSocketImpl();
253: checkOldImpl();
254: } else {
255: // No need to do a checkOldImpl() here, we know it's an up to date
256: // SocketImpl!
257: impl = new PlainSocketImpl();
258: }
259: if (impl != null)
260: impl.setServerSocket(this );
261: }
262:
263: /**
264: * Creates the socket implementation.
265: *
266: * @throws IOException if creation fails
267: * @since 1.4
268: */
269: void createImpl() throws SocketException {
270: setImpl();
271: try {
272: impl.create(true);
273: created = true;
274: } catch (IOException e) {
275: throw new SocketException(e.getMessage());
276: }
277: }
278:
279: /**
280: *
281: * Binds the <code>ServerSocket</code> to a specific address
282: * (IP address and port number).
283: * <p>
284: * If the address is <code>null</code>, then the system will pick up
285: * an ephemeral port and a valid local address to bind the socket.
286: * <p>
287: * @param endpoint The IP address & port number to bind to.
288: * @throws IOException if the bind operation fails, or if the socket
289: * is already bound.
290: * @throws SecurityException if a <code>SecurityManager</code> is present and
291: * its <code>checkListen</code> method doesn't allow the operation.
292: * @throws IllegalArgumentException if endpoint is a
293: * SocketAddress subclass not supported by this socket
294: * @since 1.4
295: */
296: public void bind(SocketAddress endpoint) throws IOException {
297: bind(endpoint, 50);
298: }
299:
300: /**
301: *
302: * Binds the <code>ServerSocket</code> to a specific address
303: * (IP address and port number).
304: * <p>
305: * If the address is <code>null</code>, then the system will pick up
306: * an ephemeral port and a valid local address to bind the socket.
307: * <P>
308: * The <code>backlog</code> argument must be a positive
309: * value greater than 0. If the value passed if equal or less
310: * than 0, then the default value will be assumed.
311: * @param endpoint The IP address & port number to bind to.
312: * @param backlog The listen backlog length.
313: * @throws IOException if the bind operation fails, or if the socket
314: * is already bound.
315: * @throws SecurityException if a <code>SecurityManager</code> is present and
316: * its <code>checkListen</code> method doesn't allow the operation.
317: * @throws IllegalArgumentException if endpoint is a
318: * SocketAddress subclass not supported by this socket
319: * @since 1.4
320: */
321: public void bind(SocketAddress endpoint, int backlog)
322: throws IOException {
323: if (isClosed())
324: throw new SocketException("Socket is closed");
325: if (!oldImpl && isBound())
326: throw new SocketException("Already bound");
327: if (endpoint == null)
328: endpoint = new InetSocketAddress(0);
329: if (!(endpoint instanceof InetSocketAddress))
330: throw new IllegalArgumentException(
331: "Unsupported address type");
332: InetSocketAddress epoint = (InetSocketAddress) endpoint;
333: if (epoint.isUnresolved())
334: throw new SocketException("Unresolved address");
335: if (backlog < 1)
336: backlog = 50;
337: try {
338: SecurityManager security = System.getSecurityManager();
339: if (security != null)
340: security.checkListen(epoint.getPort());
341: getImpl().bind(epoint.getAddress(), epoint.getPort());
342: getImpl().listen(backlog);
343: bound = true;
344: } catch (SecurityException e) {
345: bound = false;
346: throw e;
347: } catch (IOException e) {
348: bound = false;
349: throw e;
350: }
351: }
352:
353: /**
354: * Returns the local address of this server socket.
355: *
356: * @return the address to which this socket is bound,
357: * or <code>null</code> if the socket is unbound.
358: */
359: public InetAddress getInetAddress() {
360: if (!isBound())
361: return null;
362: try {
363: return getImpl().getInetAddress();
364: } catch (SocketException e) {
365: // nothing
366: // If we're bound, the the impl has been created
367: // so we shouldn't get here
368: }
369: return null;
370: }
371:
372: /**
373: * Returns the port on which this socket is listening.
374: *
375: * @return the port number to which this socket is listening or
376: * -1 if the socket is not bound yet.
377: */
378: public int getLocalPort() {
379: if (!isBound())
380: return -1;
381: try {
382: return getImpl().getLocalPort();
383: } catch (SocketException e) {
384: // nothing
385: // If we're bound, the the impl has been created
386: // so we shouldn't get here
387: }
388: return -1;
389: }
390:
391: /**
392: * Returns the address of the endpoint this socket is bound to, or
393: * <code>null</code> if it is not bound yet.
394: *
395: * @return a <code>SocketAddress</code> representing the local endpoint of this
396: * socket, or <code>null</code> if it is not bound yet.
397: * @see #getInetAddress()
398: * @see #getLocalPort()
399: * @see #bind(SocketAddress)
400: * @since 1.4
401: */
402:
403: public SocketAddress getLocalSocketAddress() {
404: if (!isBound())
405: return null;
406: return new InetSocketAddress(getInetAddress(), getLocalPort());
407: }
408:
409: /**
410: * Listens for a connection to be made to this socket and accepts
411: * it. The method blocks until a connection is made.
412: *
413: * <p>A new Socket <code>s</code> is created and, if there
414: * is a security manager,
415: * the security manager's <code>checkAccept</code> method is called
416: * with <code>s.getInetAddress().getHostAddress()</code> and
417: * <code>s.getPort()</code>
418: * as its arguments to ensure the operation is allowed.
419: * This could result in a SecurityException.
420: *
421: * @exception IOException if an I/O error occurs when waiting for a
422: * connection.
423: * @exception SecurityException if a security manager exists and its
424: * <code>checkListen</code> method doesn't allow the operation.
425: * @exception SocketTimeoutException if a timeout was previously set with setSoTimeout and
426: * the timeout has been reached.
427: *
428: * @return the new Socket
429: * @see SecurityManager#checkAccept
430: * @revised 1.4
431: * @spec JSR-51
432: */
433: public Socket accept() throws IOException {
434: if (isClosed())
435: throw new SocketException("Socket is closed");
436: if (!isBound())
437: throw new SocketException("Socket is not bound yet");
438: Socket s = new Socket((SocketImpl) null);
439: implAccept(s);
440: return s;
441: }
442:
443: /**
444: * Subclasses of ServerSocket use this method to override accept()
445: * to return their own subclass of socket. So a FooServerSocket
446: * will typically hand this method an <i>empty</i> FooSocket. On
447: * return from implAccept the FooSocket will be connected to a client.
448: *
449: * @param s the Socket
450: * @throws IOException if an I/O error occurs when waiting
451: * for a connection.
452: * @since JDK1.1
453: * @revised 1.4
454: * @spec JSR-51
455: */
456: protected final void implAccept(Socket s) throws IOException {
457: SocketImpl si = null;
458: try {
459: if (s.impl == null)
460: s.setImpl();
461: si = s.impl;
462: s.impl = null;
463: si.address = new InetAddress();
464: si.fd = new FileDescriptor();
465: getImpl().accept(si);
466:
467: SecurityManager security = System.getSecurityManager();
468: if (security != null) {
469: security.checkAccept(si.getInetAddress()
470: .getHostAddress(), si.getPort());
471: }
472: } catch (IOException e) {
473: if (si != null)
474: si.reset();
475: s.impl = si;
476: throw e;
477: } catch (SecurityException e) {
478: if (si != null)
479: si.reset();
480: s.impl = si;
481: throw e;
482: }
483: s.impl = si;
484: s.postAccept();
485: }
486:
487: /**
488: * Closes this socket.
489: *
490: * Any thread currently blocked in {@link #accept()} will throw
491: * a {@link SocketException}.
492: *
493: * @exception IOException if an I/O error occurs when closing the socket.
494: * @revised 1.4
495: * @spec JSR-51
496: */
497: public void close() throws IOException {
498: synchronized (closeLock) {
499: if (isClosed())
500: return;
501: if (created)
502: impl.close();
503: closed = true;
504: }
505: }
506:
507: /**
508: * Returns the binding state of the ServerSocket.
509: *
510: * @return true if the ServerSocket succesfuly bound to an address
511: * @since 1.4
512: */
513: public boolean isBound() {
514: // Before 1.3 ServerSockets were always bound during creation
515: return bound || oldImpl;
516: }
517:
518: /**
519: * Returns the closed state of the ServerSocket.
520: *
521: * @return true if the socket has been closed
522: * @since 1.4
523: */
524: public boolean isClosed() {
525: synchronized (closeLock) {
526: return closed;
527: }
528: }
529:
530: /**
531: * Enable/disable SO_TIMEOUT with the specified timeout, in
532: * milliseconds. With this option set to a non-zero timeout,
533: * a call to accept() for this ServerSocket
534: * will block for only this amount of time. If the timeout expires,
535: * a <B>java.net.SocketTimeoutException</B> is raised, though the
536: * ServerSocket is still valid. The option <B>must</B> be enabled
537: * prior to entering the blocking operation to have effect. The
538: * timeout must be > 0.
539: * A timeout of zero is interpreted as an infinite timeout.
540: * @param timeout the specified timeout, in milliseconds
541: * @exception SocketException if there is an error in
542: * the underlying protocol, such as a TCP error.
543: * @since JDK1.1
544: * @see #getSoTimeout()
545: */
546: public synchronized void setSoTimeout(int timeout)
547: throws SocketException {
548: if (isClosed())
549: throw new SocketException("Socket is closed");
550: getImpl().setOption(SocketOptions.SO_TIMEOUT,
551: new Integer(timeout));
552: }
553:
554: /**
555: * Retrive setting for SO_TIMEOUT. 0 returns implies that the
556: * option is disabled (i.e., timeout of infinity).
557: * @return the SO_TIMEOUT value
558: * @exception IOException if an I/O error occurs
559: * @since JDK1.1
560: * @see #setSoTimeout(int)
561: */
562: public synchronized int getSoTimeout() throws IOException {
563: if (isClosed())
564: throw new SocketException("Socket is closed");
565: Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
566: /* extra type safety */
567: if (o instanceof Integer) {
568: return ((Integer) o).intValue();
569: } else {
570: return 0;
571: }
572: }
573:
574: /**
575: * Enable/disable the SO_REUSEADDR socket option.
576: * <p>
577: * When a TCP connection is closed the connection may remain
578: * in a timeout state for a period of time after the connection
579: * is closed (typically known as the <tt>TIME_WAIT</tt> state
580: * or <tt>2MSL</tt> wait state).
581: * For applications using a well known socket address or port
582: * it may not be possible to bind a socket to the required
583: * <tt>SocketAddress</tt> if there is a connection in the
584: * timeout state involving the socket address or port.
585: * <p>
586: * Enabling <tt>SO_REUSEADDR</tt> prior to binding the socket
587: * using {@link #bind(SocketAddress)} allows the socket to be
588: * bound even though a previous connection is in a timeout
589: * state.
590: * <p>
591: * When a <tt>ServerSocket</tt> is created the initial setting
592: * of <tt>SO_REUSEADDR</tt> is not defined. Applications can
593: * use {@link getReuseAddress()} to determine the initial
594: * setting of <tt>SO_REUSEADDR</tt>.
595: * <p>
596: * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
597: * disabled after a socket is bound (See {@link #isBound()})
598: * is not defined.
599: *
600: * @param on whether to enable or disable the socket option
601: * @exception SocketException if an error occurs enabling or
602: * disabling the <tt>SO_RESUEADDR</tt> socket option,
603: * or the socket is closed.
604: * @since 1.4
605: * @see #getReuseAddress()
606: * @see #bind(SocketAddress)
607: * @see #isBound()
608: * @see #isClosed()
609: */
610: public void setReuseAddress(boolean on) throws SocketException {
611: if (isClosed())
612: throw new SocketException("Socket is closed");
613: getImpl()
614: .setOption(SocketOptions.SO_REUSEADDR, new Boolean(on));
615: }
616:
617: /**
618: * Tests if SO_REUSEADDR is enabled.
619: *
620: * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
621: * @exception SocketException if there is an error
622: * in the underlying protocol, such as a TCP error.
623: * @since 1.4
624: * @see #setReuseAddress(boolean)
625: */
626: public boolean getReuseAddress() throws SocketException {
627: if (isClosed())
628: throw new SocketException("Socket is closed");
629: return ((Boolean) (getImpl()
630: .getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
631: }
632:
633: /**
634: * Returns the implementation address and implementation port of
635: * this socket as a <code>String</code>.
636: *
637: * @return a string representation of this socket.
638: */
639: public String toString() {
640: if (!isBound())
641: return "ServerSocket[unbound]";
642: return "ServerSocket[addr=" + impl.getInetAddress() + ",port="
643: + impl.getPort() + ",localport=" + impl.getLocalPort()
644: + "]";
645: }
646:
647: void setBound() {
648: bound = true;
649: }
650:
651: void setCreated() {
652: created = true;
653: }
654:
655: /**
656: * The factory for all server sockets.
657: */
658: private static SocketImplFactory factory;
659:
660: /**
661: * Sets the server socket implementation factory for the
662: * application. The factory can be specified only once.
663: * <p>
664: * When an application creates a new server socket, the socket
665: * implementation factory's <code>createSocketImpl</code> method is
666: * called to create the actual socket implementation.
667: * <p>
668: * If there is a security manager, this method first calls
669: * the security manager's <code>checkSetFactory</code> method
670: * to ensure the operation is allowed.
671: * This could result in a SecurityException.
672: *
673: * @param fac the desired factory.
674: * @exception IOException if an I/O error occurs when setting the
675: * socket factory.
676: * @exception SocketException if the factory has already been defined.
677: * @exception SecurityException if a security manager exists and its
678: * <code>checkSetFactory</code> method doesn't allow the operation.
679: * @see java.net.SocketImplFactory#createSocketImpl()
680: * @see SecurityManager#checkSetFactory
681: */
682: public static synchronized void setSocketFactory(
683: SocketImplFactory fac) throws IOException {
684: if (factory != null) {
685: throw new SocketException("factory already defined");
686: }
687: SecurityManager security = System.getSecurityManager();
688: if (security != null) {
689: security.checkSetFactory();
690: }
691: factory = fac;
692: }
693:
694: /**
695: * Sets a default proposed value for the SO_RCVBUF option for sockets
696: * accepted from this <tt>ServerSocket</tt>. The value actually set
697: * in the accepted socket must be determined by calling
698: * {@link Socket#getReceiveBufferSize()} after the socket
699: * is returned by {@link #accept()}.
700: * <p>
701: * The value of SO_RCVBUF is used both to set the size of the internal
702: * socket receive buffer, and to set the size of the TCP receive window
703: * that is advertized to the remote peer.
704: * <p>
705: * It is possible to change the value subsequently, by calling
706: * {@link Socket#setReceiveBufferSize(int)}. However, if the application
707: * wishes to allow a receive window larger than 64K bytes, as defined by RFC1323
708: * then the proposed value must be set in the ServerSocket <B>before</B>
709: * it is bound to a local address. This implies, that the ServerSocket must be
710: * created with the no-argument constructor, then setReceiveBufferSize() must
711: * be called and lastly the ServerSocket is bound to an address by calling bind().
712: * <p>
713: * Failure to do this will not cause an error, and the buffer size may be set to the
714: * requested value but the TCP receive window in sockets accepted from
715: * this ServerSocket will be no larger than 64K bytes.
716: *
717: * @exception SocketException if there is an error
718: * in the underlying protocol, such as a TCP error.
719: *
720: * @param size the size to which to set the receive buffer
721: * size. This value must be greater than 0.
722: *
723: * @exception IllegalArgumentException if the
724: * value is 0 or is negative.
725: *
726: * @since 1.4
727: * @see #getReceiveBufferSize
728: */
729: public synchronized void setReceiveBufferSize(int size)
730: throws SocketException {
731: if (!(size > 0)) {
732: throw new IllegalArgumentException("negative receive size");
733: }
734: if (isClosed())
735: throw new SocketException("Socket is closed");
736: getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
737: }
738:
739: /**
740: * Gets the value of the SO_RCVBUF option for this <tt>ServerSocket</tt>,
741: * that is the proposed buffer size that will be used for Sockets accepted
742: * from this <tt>ServerSocket</tt>.
743: *
744: * <p>Note, the value actually set in the accepted socket is determined by
745: * calling {@link Socket#getReceiveBufferSize()}.
746: * @return the value of the SO_RCVBUF option for this <tt>Socket</tt>.
747: * @exception SocketException if there is an error
748: * in the underlying protocol, such as a TCP error.
749: * @see #setReceiveBufferSize(int)
750: * @since 1.4
751: */
752: public synchronized int getReceiveBufferSize()
753: throws SocketException {
754: if (isClosed())
755: throw new SocketException("Socket is closed");
756: int result = 0;
757: Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
758: if (o instanceof Integer) {
759: result = ((Integer) o).intValue();
760: }
761: return result;
762: }
763: }
|