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