History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/net/ServerSocket.java (1 of 18352 files). Show all

Unified · Split

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