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