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+
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+ * 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+}