1 /* ServerSocket.java -- Class for implementing server side sockets
2 Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2006
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
41 import gnu
.java
.net
.PlainSocketImpl
;
43 import java
.io
.IOException
;
44 import java
.nio
.channels
.IllegalBlockingModeException
;
45 import java
.nio
.channels
.ServerSocketChannel
;
48 /* Written using on-line Java Platform 1.2 API Specification.
49 * Status: I believe all methods are implemented.
53 * This class models server side sockets. The basic model is that the
54 * server socket is created and bound to some well known port. It then
55 * listens for and accepts connections. At that point the client and
56 * server sockets are ready to communicate with one another utilizing
57 * whatever application layer protocol they desire.
59 * As with the <code>Socket</code> class, most instance methods of this class
60 * simply redirect their calls to an implementation class.
62 * @author Aaron M. Renn (arenn@urbanophile.com)
63 * @author Per Bothner (bothner@cygnus.com)
65 public class ServerSocket
68 * This is the user defined SocketImplFactory, if one is supplied
70 private static SocketImplFactory factory
;
73 * This is the SocketImp object to which most instance methods in this
74 * class are redirected
76 private SocketImpl impl
;
79 * We need to retain the local address even after the socket is closed.
81 private InetSocketAddress local
;
85 * This constructor is only used by java.nio.
88 // FIXME: Workaround a bug in gcj.
89 //ServerSocket (PlainSocketImpl impl) throws IOException
90 ServerSocket(SocketImpl impl
) throws IOException
93 throw new NullPointerException("impl may not be null");
96 this.impl
.create(true);
97 setReuseAddress(true);
101 * This method is only used by java.nio.
104 // FIXME: Workaround a bug in gcj.
105 //PlainSocketImpl getImpl()
112 * Constructor that simply sets the implementation.
114 * @exception IOException If an error occurs
116 * @specnote This constructor is public since JDK 1.4
118 public ServerSocket() throws IOException
121 impl
= factory
.createSocketImpl();
123 impl
= new PlainSocketImpl();
129 * Creates a server socket and binds it to the specified port. If the
130 * port number is 0, a random free port will be chosen. The pending
131 * connection queue on this socket will be set to 50.
133 * @param port The port number to bind to
135 * @exception IOException If an error occurs
136 * @exception SecurityException If a security manager exists and its
137 * checkListen method doesn't allow the operation
139 public ServerSocket(int port
) throws IOException
145 * Creates a server socket and binds it to the specified port. If the
146 * port number is 0, a random free port will be chosen. The pending
147 * connection queue on this socket will be set to the value passed as
150 * @param port The port number to bind to
151 * @param backlog The length of the pending connection queue
153 * @exception IOException If an error occurs
154 * @exception SecurityException If a security manager exists and its
155 * checkListen method doesn't allow the operation
157 public ServerSocket(int port
, int backlog
) throws IOException
159 this(port
, backlog
, null);
163 * Creates a server socket and binds it to the specified port. If the
164 * port number is 0, a random free port will be chosen. The pending
165 * connection queue on this socket will be set to the value passed as
166 * backlog. The third argument specifies a particular local address to
167 * bind t or null to bind to all local address.
169 * @param port The port number to bind to
170 * @param backlog The length of the pending connection queue
171 * @param bindAddr The address to bind to, or null to bind to all addresses
173 * @exception IOException If an error occurs
174 * @exception SecurityException If a security manager exists and its
175 * checkListen method doesn't allow the operation
179 public ServerSocket(int port
, int backlog
, InetAddress bindAddr
)
184 // bind/listen socket
185 bind(new InetSocketAddress(bindAddr
, port
), backlog
);
189 * Binds the server socket to a specified socket address
191 * @param endpoint The socket address to bind to
193 * @exception IOException If an error occurs
194 * @exception IllegalArgumentException If address type is not supported
195 * @exception SecurityException If a security manager exists and its
196 * checkListen method doesn't allow the operation
200 public void bind(SocketAddress endpoint
) throws IOException
206 * Binds the server socket to a specified socket address
208 * @param endpoint The socket address to bind to
209 * @param backlog The length of the pending connection queue
211 * @exception IOException If an error occurs
212 * @exception IllegalArgumentException If address type is not supported
213 * @exception SecurityException If a security manager exists and its
214 * checkListen method doesn't allow the operation
218 public void bind(SocketAddress endpoint
, int backlog
)
222 throw new SocketException("ServerSocket is closed");
225 throw new SocketException("Already bound");
230 if (endpoint
== null)
232 addr
= InetAddress
.ANY_IF
;
235 else if (! (endpoint
instanceof InetSocketAddress
))
237 throw new IllegalArgumentException("Address type not supported");
241 InetSocketAddress tmp
= (InetSocketAddress
) endpoint
;
242 if (tmp
.isUnresolved())
243 throw new SocketException("Unresolved address");
244 addr
= tmp
.getAddress();
245 port
= tmp
.getPort();
248 SecurityManager s
= System
.getSecurityManager();
254 impl
.bind(addr
, port
);
255 impl
.listen(backlog
);
257 local
= new InetSocketAddress(
258 (InetAddress
) impl
.getOption(SocketOptions
.SO_BINDADDR
),
259 impl
.getLocalPort());
268 catch (IOException _
)
275 * This method returns the local address to which this socket is bound
277 * @return The socket's local address
279 public InetAddress
getInetAddress()
284 return local
.getAddress();
288 * This method returns the local port number to which this socket is bound
290 * @return The socket's port number
292 public int getLocalPort()
297 return local
.getPort();
301 * Returns the local socket address
303 * @return the local socket address, null if not bound
307 public SocketAddress
getLocalSocketAddress()
313 * Accepts a new connection and returns a connected <code>Socket</code>
314 * instance representing that connection. This method will block until a
315 * connection is available.
317 * @return socket object for the just accepted connection
319 * @exception IOException If an error occurs
320 * @exception SecurityException If a security manager exists and its
321 * checkListen method doesn't allow the operation
322 * @exception IllegalBlockingModeException If this socket has an associated
323 * channel, and the channel is in non-blocking mode
324 * @exception SocketTimeoutException If a timeout was previously set with
325 * setSoTimeout and the timeout has been reached
327 public Socket
accept() throws IOException
329 Socket socket
= new Socket();
335 catch (IOException e
)
341 catch (IOException e2
)
348 catch (SecurityException e
)
354 catch (IOException e2
)
366 * This protected method is used to help subclasses override
367 * <code>ServerSocket.accept()</code>. The passed in socket will be
368 * connected when this method returns.
370 * @param socket The socket that is used for the accepted connection
372 * @exception IOException If an error occurs
373 * @exception IllegalBlockingModeException If this socket has an associated
374 * channel, and the channel is in non-blocking mode
378 protected final void implAccept(Socket socket
) throws IOException
381 throw new SocketException("ServerSocket is closed");
383 // The Sun spec says that if we have an associated channel and
384 // it is in non-blocking mode, we throw an IllegalBlockingModeException.
385 // However, in our implementation if the channel itself initiated this
386 // operation, then we must honor it regardless of its blocking mode.
387 if (getChannel() != null && ! getChannel().isBlocking()
388 && ! ((PlainSocketImpl
) getImpl()).isInChannelOperation())
389 throw new IllegalBlockingModeException();
391 impl
.accept(socket
.impl
);
394 SecurityManager sm
= System
.getSecurityManager();
396 sm
.checkAccept(socket
.getInetAddress().getHostAddress(),
401 * Closes this socket and stops listening for connections
403 * @exception IOException If an error occurs
405 public void close() throws IOException
415 * Returns the unique <code>ServerSocketChannel</code> object
416 * associated with this socket, if any.
418 * <p>The socket only has a <code>ServerSocketChannel</code> if its created
419 * by <code>ServerSocketChannel.open()</code>.</p>
421 * @return the associated socket channel, null if none exists
425 public ServerSocketChannel
getChannel()
431 * Returns true when the socket is bound, otherwise false
433 * @return true if socket is bound, false otherwise
437 public boolean isBound()
439 return local
!= null;
443 * Returns true if the socket is closed, otherwise false
445 * @return true if socket is closed, false otherwise
449 public boolean isClosed()
451 ServerSocketChannel channel
= getChannel();
452 return impl
== null || (channel
!= null && ! channel
.isOpen());
456 * Sets the value of SO_TIMEOUT. A value of 0 implies that SO_TIMEOUT is
457 * disabled (ie, operations never time out). This is the number of
458 * milliseconds a socket operation can block before an
459 * InterruptedIOException is thrown.
461 * @param timeout The new SO_TIMEOUT value
463 * @exception SocketException If an error occurs
467 public void setSoTimeout(int timeout
) throws SocketException
470 throw new SocketException("ServerSocket is closed");
473 throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
475 impl
.setOption(SocketOptions
.SO_TIMEOUT
, new Integer(timeout
));
479 * Retrieves the current value of the SO_TIMEOUT setting. A value of 0
480 * implies that SO_TIMEOUT is disabled (ie, operations never time out).
481 * This is the number of milliseconds a socket operation can block before
482 * an InterruptedIOException is thrown.
484 * @return The value of SO_TIMEOUT
486 * @exception IOException If an error occurs
490 public int getSoTimeout() throws IOException
493 throw new SocketException("ServerSocket is closed");
495 Object timeout
= impl
.getOption(SocketOptions
.SO_TIMEOUT
);
497 if (! (timeout
instanceof Integer
))
498 throw new IOException("Internal Error");
500 return ((Integer
) timeout
).intValue();
504 * Enables/Disables the SO_REUSEADDR option
506 * @param on true if SO_REUSEADDR should be enabled, false otherwise
508 * @exception SocketException If an error occurs
512 public void setReuseAddress(boolean on
) throws SocketException
515 throw new SocketException("ServerSocket is closed");
517 impl
.setOption(SocketOptions
.SO_REUSEADDR
, Boolean
.valueOf(on
));
521 * Checks if the SO_REUSEADDR option is enabled
523 * @return true if SO_REUSEADDR is set, false otherwise
525 * @exception SocketException If an error occurs
529 public boolean getReuseAddress() throws SocketException
532 throw new SocketException("ServerSocket is closed");
534 Object reuseaddr
= impl
.getOption(SocketOptions
.SO_REUSEADDR
);
536 if (! (reuseaddr
instanceof Boolean
))
537 throw new SocketException("Internal Error");
539 return ((Boolean
) reuseaddr
).booleanValue();
543 * This method sets the value for the system level socket option
544 * SO_RCVBUF to the specified value. Note that valid values for this
545 * option are specific to a given operating system.
547 * @param size The new receive buffer size.
549 * @exception SocketException If an error occurs or Socket is not connected
550 * @exception IllegalArgumentException If size is 0 or negative
554 public void setReceiveBufferSize(int size
) throws SocketException
557 throw new SocketException("ServerSocket is closed");
560 throw new IllegalArgumentException("SO_RCVBUF value must be > 0");
562 impl
.setOption(SocketOptions
.SO_RCVBUF
, new Integer(size
));
566 * This method returns the value of the system level socket option
567 * SO_RCVBUF, which is used by the operating system to tune buffer
568 * sizes for data transfers.
570 * @return The receive buffer size.
572 * @exception SocketException If an error occurs or Socket is not connected
576 public int getReceiveBufferSize() throws SocketException
579 throw new SocketException("ServerSocket is closed");
581 Object buf
= impl
.getOption(SocketOptions
.SO_RCVBUF
);
583 if (! (buf
instanceof Integer
))
584 throw new SocketException("Internal Error: Unexpected type");
586 return ((Integer
) buf
).intValue();
590 * Returns the value of this socket as a <code>String</code>.
592 * @return This socket represented as a <code>String</code>.
594 public String
toString()
597 return "ServerSocket[unbound]";
599 return ("ServerSocket[addr=" + getInetAddress() + ",port="
600 + port
+ ",localport=" + getLocalPort() + "]");
604 * Sets the <code>SocketImplFactory</code> for all
605 * <code>ServerSocket</code>'s. This may only be done
606 * once per virtual machine. Subsequent attempts will generate an
607 * exception. Note that a <code>SecurityManager</code> check is made prior
608 * to setting the factory. If insufficient privileges exist to set the
609 * factory, an exception will be thrown
611 * @param fac the factory to set
613 * @exception SecurityException If this operation is not allowed by the
614 * <code>SecurityManager</code>.
615 * @exception SocketException If the factory object is already defined
616 * @exception IOException If any other error occurs
618 public static synchronized void setSocketFactory(SocketImplFactory fac
)
622 throw new SocketException("SocketFactory already defined");
624 SecurityManager sm
= System
.getSecurityManager();
626 sm
.checkSetFactory();