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
;
84 * This constructor is only used by java.nio.
87 // FIXME: Workaround a bug in gcj.
88 //ServerSocket (PlainSocketImpl impl) throws IOException
89 ServerSocket(SocketImpl impl
) throws IOException
92 throw new NullPointerException("impl may not be null");
95 this.impl
.create(true);
99 * This method is only used by java.nio.
102 // FIXME: Workaround a bug in gcj.
103 //PlainSocketImpl getImpl()
110 * Constructor that simply sets the implementation.
112 * @exception IOException If an error occurs
114 * @specnote This constructor is public since JDK 1.4
116 public ServerSocket() throws IOException
119 impl
= factory
.createSocketImpl();
121 impl
= new PlainSocketImpl();
127 * Creates a server socket and binds it to the specified port. If the
128 * port number is 0, a random free port will be chosen. The pending
129 * connection queue on this socket will be set to 50.
131 * @param port The port number to bind to
133 * @exception IOException If an error occurs
134 * @exception SecurityException If a security manager exists and its
135 * checkListen method doesn't allow the operation
137 public ServerSocket(int port
) throws IOException
143 * Creates a server socket and binds it to the specified port. If the
144 * port number is 0, a random free port will be chosen. The pending
145 * connection queue on this socket will be set to the value passed as
148 * @param port The port number to bind to
149 * @param backlog The length of the pending connection queue
151 * @exception IOException If an error occurs
152 * @exception SecurityException If a security manager exists and its
153 * checkListen method doesn't allow the operation
155 public ServerSocket(int port
, int backlog
) throws IOException
157 this(port
, backlog
, null);
161 * Creates a server socket and binds it to the specified port. If the
162 * port number is 0, a random free port will be chosen. The pending
163 * connection queue on this socket will be set to the value passed as
164 * backlog. The third argument specifies a particular local address to
165 * bind t or null to bind to all local address.
167 * @param port The port number to bind to
168 * @param backlog The length of the pending connection queue
169 * @param bindAddr The address to bind to, or null to bind to all addresses
171 * @exception IOException If an error occurs
172 * @exception SecurityException If a security manager exists and its
173 * checkListen method doesn't allow the operation
177 public ServerSocket(int port
, int backlog
, InetAddress bindAddr
)
182 // bind/listen socket
183 bind(new InetSocketAddress(bindAddr
, port
), backlog
);
187 * Binds the server socket to a specified socket address
189 * @param endpoint The socket address to bind to
191 * @exception IOException If an error occurs
192 * @exception IllegalArgumentException If address type is not supported
193 * @exception SecurityException If a security manager exists and its
194 * checkListen method doesn't allow the operation
198 public void bind(SocketAddress endpoint
) throws IOException
204 * Binds the server socket to a specified socket address
206 * @param endpoint The socket address to bind to
207 * @param backlog The length of the pending connection queue
209 * @exception IOException If an error occurs
210 * @exception IllegalArgumentException If address type is not supported
211 * @exception SecurityException If a security manager exists and its
212 * checkListen method doesn't allow the operation
216 public void bind(SocketAddress endpoint
, int backlog
)
220 throw new SocketException("ServerSocket is closed");
222 if (! (endpoint
instanceof InetSocketAddress
))
223 throw new IllegalArgumentException("Address type not supported");
225 InetSocketAddress tmp
= (InetSocketAddress
) endpoint
;
227 SecurityManager s
= System
.getSecurityManager();
229 s
.checkListen(tmp
.getPort());
231 InetAddress addr
= tmp
.getAddress();
233 // Initialize addr with 0.0.0.0.
235 addr
= InetAddress
.ANY_IF
;
239 impl
.bind(addr
, tmp
.getPort());
240 impl
.listen(backlog
);
241 local
= new InetSocketAddress(
242 (InetAddress
) impl
.getOption(SocketOptions
.SO_BINDADDR
),
243 impl
.getLocalPort());
245 catch (IOException exception
)
250 catch (RuntimeException exception
)
263 * This method returns the local address to which this socket is bound
265 * @return The socket's local address
267 public InetAddress
getInetAddress()
272 return local
.getAddress();
276 * This method returns the local port number to which this socket is bound
278 * @return The socket's port number
280 public int getLocalPort()
285 return local
.getPort();
289 * Returns the local socket address
291 * @return the local socket address, null if not bound
295 public SocketAddress
getLocalSocketAddress()
301 * Accepts a new connection and returns a connected <code>Socket</code>
302 * instance representing that connection. This method will block until a
303 * connection is available.
305 * @return socket object for the just accepted connection
307 * @exception IOException If an error occurs
308 * @exception SecurityException If a security manager exists and its
309 * checkListen method doesn't allow the operation
310 * @exception IllegalBlockingModeException If this socket has an associated
311 * channel, and the channel is in non-blocking mode
312 * @exception SocketTimeoutException If a timeout was previously set with
313 * setSoTimeout and the timeout has been reached
315 public Socket
accept() throws IOException
317 Socket socket
= new Socket();
323 catch (IOException e
)
329 catch (IOException e2
)
341 * This protected method is used to help subclasses override
342 * <code>ServerSocket.accept()</code>. The passed in socket will be
343 * connected when this method returns.
345 * @param socket The socket that is used for the accepted connection
347 * @exception IOException If an error occurs
348 * @exception IllegalBlockingModeException If this socket has an associated
349 * channel, and the channel is in non-blocking mode
353 protected final void implAccept(Socket socket
) throws IOException
356 throw new SocketException("ServerSocket is closed");
358 // FIXME: Add a security check to make sure we're allowed to
359 // connect to the remote host.
361 // The Sun spec says that if we have an associated channel and
362 // it is in non-blocking mode, we throw an IllegalBlockingModeException.
363 // However, in our implementation if the channel itself initiated this
364 // operation, then we must honor it regardless of its blocking mode.
365 if (getChannel() != null && ! getChannel().isBlocking()
366 && ! ((PlainSocketImpl
) getImpl()).isInChannelOperation())
367 throw new IllegalBlockingModeException();
369 impl
.accept(socket
.impl
);
370 socket
.implCreated
= true;
375 * Closes this socket and stops listening for connections
377 * @exception IOException If an error occurs
379 public void close() throws IOException
387 if (getChannel() != null)
388 getChannel().close();
392 * Returns the unique <code>ServerSocketChannel</code> object
393 * associated with this socket, if any.
395 * <p>The socket only has a <code>ServerSocketChannel</code> if its created
396 * by <code>ServerSocketChannel.open()</code>.</p>
398 * @return the associated socket channel, null if none exists
402 public ServerSocketChannel
getChannel()
408 * Returns true when the socket is bound, otherwise false
410 * @return true if socket is bound, false otherwise
414 public boolean isBound()
416 return local
!= null;
420 * Returns true if the socket is closed, otherwise false
422 * @return true if socket is closed, false otherwise
426 public boolean isClosed()
432 * Sets the value of SO_TIMEOUT. A value of 0 implies that SO_TIMEOUT is
433 * disabled (ie, operations never time out). This is the number of
434 * milliseconds a socket operation can block before an
435 * InterruptedIOException is thrown.
437 * @param timeout The new SO_TIMEOUT value
439 * @exception SocketException If an error occurs
443 public void setSoTimeout(int timeout
) throws SocketException
446 throw new SocketException("ServerSocket is closed");
449 throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
451 impl
.setOption(SocketOptions
.SO_TIMEOUT
, new Integer(timeout
));
455 * Retrieves the current value of the SO_TIMEOUT setting. A value of 0
456 * implies that SO_TIMEOUT is disabled (ie, operations never time out).
457 * This is the number of milliseconds a socket operation can block before
458 * an InterruptedIOException is thrown.
460 * @return The value of SO_TIMEOUT
462 * @exception IOException If an error occurs
466 public int getSoTimeout() throws IOException
469 throw new SocketException("ServerSocket is closed");
471 Object timeout
= impl
.getOption(SocketOptions
.SO_TIMEOUT
);
473 if (! (timeout
instanceof Integer
))
474 throw new IOException("Internal Error");
476 return ((Integer
) timeout
).intValue();
480 * Enables/Disables the SO_REUSEADDR option
482 * @param on true if SO_REUSEADDR should be enabled, false otherwise
484 * @exception SocketException If an error occurs
488 public void setReuseAddress(boolean on
) throws SocketException
491 throw new SocketException("ServerSocket is closed");
493 impl
.setOption(SocketOptions
.SO_REUSEADDR
, Boolean
.valueOf(on
));
497 * Checks if the SO_REUSEADDR option is enabled
499 * @return true if SO_REUSEADDR is set, false otherwise
501 * @exception SocketException If an error occurs
505 public boolean getReuseAddress() throws SocketException
508 throw new SocketException("ServerSocket is closed");
510 Object reuseaddr
= impl
.getOption(SocketOptions
.SO_REUSEADDR
);
512 if (! (reuseaddr
instanceof Boolean
))
513 throw new SocketException("Internal Error");
515 return ((Boolean
) reuseaddr
).booleanValue();
519 * This method sets the value for the system level socket option
520 * SO_RCVBUF to the specified value. Note that valid values for this
521 * option are specific to a given operating system.
523 * @param size The new receive buffer size.
525 * @exception SocketException If an error occurs or Socket is not connected
526 * @exception IllegalArgumentException If size is 0 or negative
530 public void setReceiveBufferSize(int size
) throws SocketException
533 throw new SocketException("ServerSocket is closed");
536 throw new IllegalArgumentException("SO_RCVBUF value must be > 0");
538 impl
.setOption(SocketOptions
.SO_RCVBUF
, new Integer(size
));
542 * This method returns the value of the system level socket option
543 * SO_RCVBUF, which is used by the operating system to tune buffer
544 * sizes for data transfers.
546 * @return The receive buffer size.
548 * @exception SocketException If an error occurs or Socket is not connected
552 public int getReceiveBufferSize() throws SocketException
555 throw new SocketException("ServerSocket is closed");
557 Object buf
= impl
.getOption(SocketOptions
.SO_RCVBUF
);
559 if (! (buf
instanceof Integer
))
560 throw new SocketException("Internal Error: Unexpected type");
562 return ((Integer
) buf
).intValue();
566 * Returns the value of this socket as a <code>String</code>.
568 * @return This socket represented as a <code>String</code>.
570 public String
toString()
573 return "ServerSocket[unbound]";
575 return ("ServerSocket[addr=" + getInetAddress() + ",port="
576 + impl
.getPort() + ",localport=" + impl
.getLocalPort() + "]");
580 * Sets the <code>SocketImplFactory</code> for all
581 * <code>ServerSocket</code>'s. This may only be done
582 * once per virtual machine. Subsequent attempts will generate an
583 * exception. Note that a <code>SecurityManager</code> check is made prior
584 * to setting the factory. If insufficient privileges exist to set the
585 * factory, an exception will be thrown
587 * @param fac the factory to set
589 * @exception SecurityException If this operation is not allowed by the
590 * <code>SecurityManager</code>.
591 * @exception SocketException If the factory object is already defined
592 * @exception IOException If any other error occurs
594 public static synchronized void setSocketFactory(SocketImplFactory fac
)