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