1 /* ServerSocket.java -- Class for implementing server side sockets
2 Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
40 import java.io.IOException;
41 import java.nio.channels.IllegalBlockingModeException;
42 import java.nio.channels.ServerSocketChannel;
44 /* Written using on-line Java Platform 1.2 API Specification.
45 * Status: I believe all methods are implemented.
49 * This class models server side sockets. The basic model is that the
50 * server socket is created and bound to some well known port. It then
51 * listens for and accepts connections. At that point the client and
52 * server sockets are ready to communicate with one another utilizing
53 * whatever application layer protocol they desire.
55 * As with the <code>Socket</code> class, most instance methods of this class
56 * simply redirect their calls to an implementation class.
58 * @author Aaron M. Renn (arenn@urbanophile.com)
59 * @author Per Bothner (bothner@cygnus.com)
61 public class ServerSocket
64 * This is the user defined SocketImplFactory, if one is supplied
66 private static SocketImplFactory factory;
69 * This is the SocketImp object to which most instance methods in this
70 * class are redirected
72 private SocketImpl impl;
75 * ServerSocketChannel of this ServerSocket. This channel only exists
76 * when the socket is created by ServerSocketChannel.open().
78 private ServerSocketChannel ch;
80 private boolean closed = false;
83 * Constructor that simply sets the implementation.
85 * @exception IOException If an error occurs
87 * @specnote This constructor is public since JDK 1.4
89 public ServerSocket() throws IOException
92 impl = factory.createSocketImpl();
94 impl = new PlainSocketImpl();
100 * Creates a server socket and binds it to the specified port. If the
101 * port number is 0, a random free port will be chosen. The pending
102 * connection queue on this socket will be set to 50.
104 * @param port The port number to bind to
106 * @exception IOException If an error occurs
107 * @exception SecurityException If a security manager exists and its
108 * checkListen method doesn't allow the operation
110 public ServerSocket (int port)
117 * Creates a server socket and binds it to the specified port. If the
118 * port number is 0, a random free port will be chosen. The pending
119 * connection queue on this socket will be set to the value passed as
122 * @param port The port number to bind to
123 * @param backlog The length of the pending connection queue
125 * @exception IOException If an error occurs
126 * @exception SecurityException If a security manager exists and its
127 * checkListen method doesn't allow the operation
129 public ServerSocket (int port, int backlog)
132 this(port, backlog, null);
136 * Creates a server socket and binds it to the specified port. If the
137 * port number is 0, a random free port will be chosen. The pending
138 * connection queue on this socket will be set to the value passed as
139 * backlog. The third argument specifies a particular local address to
140 * bind t or null to bind to all local address.
142 * @param port The port number to bind to
143 * @param backlog The length of the pending connection queue
144 * @param bindAddr The address to bind to, or null to bind to all addresses
146 * @exception IOException If an error occurs
147 * @exception SecurityException If a security manager exists and its
148 * checkListen method doesn't allow the operation
152 public ServerSocket (int port, int backlog, InetAddress bindAddr)
158 throw new IOException("Cannot initialize Socket implementation");
160 SecurityManager s = System.getSecurityManager();
164 if (bindAddr == null)
165 bindAddr = InetAddress.ANY_IF;
170 // bind to address/port
173 impl.bind(bindAddr, port);
175 catch (IOException exception)
180 catch (RuntimeException exception)
194 impl.listen(backlog);
196 catch (IOException exception)
201 catch (RuntimeException exception)
214 * Binds the server socket to a specified socket address
216 * @param endpoint The socket address to bind to
218 * @exception IOException If an error occurs
219 * @exception IllegalArgumentException If address type is not supported
220 * @exception SecurityException If a security manager exists and its
221 * checkListen method doesn't allow the operation
225 public void bind (SocketAddress endpoint)
232 * Binds the server socket to a specified socket address
234 * @param endpoint The socket address to bind to
235 * @param backlog The length of the pending connection queue
237 * @exception IOException If an error occurs
238 * @exception IllegalArgumentException If address type is not supported
239 * @exception SecurityException If a security manager exists and its
240 * checkListen method doesn't allow the operation
244 public void bind (SocketAddress endpoint, int backlog) throws IOException
247 throw new SocketException ("ServerSocket is closed");
250 throw new IOException ("Cannot initialize Socket implementation");
252 if (! (endpoint instanceof InetSocketAddress))
253 throw new IllegalArgumentException ("Address type not supported");
255 InetSocketAddress tmp = (InetSocketAddress) endpoint;
257 SecurityManager s = System.getSecurityManager ();
259 s.checkListen (tmp.getPort ());
261 impl.bind (tmp.getAddress (), tmp.getPort ());
262 impl.listen(backlog);
266 * This method returns the local address to which this socket is bound
268 * @return The socket's local address
270 public InetAddress getInetAddress()
274 return (InetAddress) impl.getOption (SocketOptions.SO_BINDADDR);
276 catch (SocketException e)
283 * This method returns the local port number to which this socket is bound
285 * @return The socket's port number
287 public int getLocalPort()
289 return impl.getLocalPort();
293 * Returns the local socket address
297 public SocketAddress getLocalSocketAddress()
299 InetAddress addr = getInetAddress();
302 return new InetSocketAddress (getInetAddress(), getLocalPort());
308 * Accepts a new connection and returns a connected <code>Socket</code>
309 * instance representing that connection. This method will block until a
310 * connection is available.
312 * @exception IOException If an error occurs
313 * @exception SecurityException If a security manager exists and its
314 * checkListen method doesn't allow the operation
315 * @exception IllegalBlockingModeException If this socket has an associated
316 * channel, and the channel is in non-blocking mode
317 * @exception SocketTimeoutException If a timeout was previously set with
318 * setSoTimeout and the timeout has been reached
320 public Socket accept () throws IOException
323 throw new IOException ("Cannot initialize Socket implementation");
325 SecurityManager sm = System.getSecurityManager ();
327 sm.checkListen (impl.getLocalPort ());
329 Socket s = new Socket();
336 * This protected method is used to help subclasses override
337 * <code>ServerSocket.accept()</code>. The passed in socket will be
338 * connected when this method returns.
340 * @param socket The socket that is used for the accepted connection
342 * @exception IOException If an error occurs
343 * @exception IllegalBlockingModeException If this socket has an associated
344 * channel, and the channel is in non-blocking mode
348 protected final void implAccept (Socket s)
351 if (ch != null && !ch.isBlocking())
352 throw new IllegalBlockingModeException();
358 * Closes this socket and stops listening for connections
360 * @exception IOException If an error occurs
362 public void close () throws IOException
374 * Returns the unique ServerSocketChannel object
375 * associated with this socket, if any.
377 * The socket only has a ServerSocketChannel if its created
378 * by ServerSocketChannel.open.
382 public ServerSocketChannel getChannel()
388 * Returns true then the socket is bound, otherwise false
392 public boolean isBound()
396 Object bindaddr = impl.getOption (SocketOptions.SO_BINDADDR);
398 catch (SocketException e)
407 * Returns true if the socket is closed, otherwise false
411 public boolean isClosed()
417 * Sets the value of SO_TIMEOUT. A value of 0 implies that SO_TIMEOUT is
418 * disabled (ie, operations never time out). This is the number of
419 * milliseconds a socket operation can block before an
420 * InterruptedIOException is thrown.
422 * @param timeout The new SO_TIMEOUT value
424 * @exception SocketException If an error occurs
428 public void setSoTimeout (int timeout) throws SocketException
431 throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
433 impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
437 * Retrieves the current value of the SO_TIMEOUT setting. A value of 0
438 * implies that SO_TIMEOUT is disabled (ie, operations never time out).
439 * This is the number of milliseconds a socket operation can block before
440 * an InterruptedIOException is thrown.
442 * @return The value of SO_TIMEOUT
444 * @exception IOException If an error occurs
448 public int getSoTimeout () throws IOException
450 Object timeout = impl.getOption(SocketOptions.SO_TIMEOUT);
452 if (!(timeout instanceof Integer))
453 throw new IOException("Internal Error");
455 return ((Integer)timeout).intValue();
459 * Enables/Disables the SO_REUSEADDR option
461 * @exception SocketException If an error occurs
465 public void setReuseAddress (boolean on)
466 throws SocketException
469 throw new SocketException ("Cannot initialize Socket implementation");
471 impl.setOption (SocketOptions.SO_REUSEADDR, new Boolean (on));
475 * Checks if the SO_REUSEADDR option is enabled
477 * @exception SocketException If an error occurs
481 public boolean getReuseAddress()
482 throws SocketException
485 throw new SocketException ("Cannot initialize Socket implementation");
487 Object reuseaddr = impl.getOption (SocketOptions.SO_REUSEADDR);
489 if (!(reuseaddr instanceof Boolean))
490 throw new SocketException ("Internal Error");
492 return ((Boolean) reuseaddr).booleanValue ();
496 * This method sets the value for the system level socket option
497 * SO_RCVBUF to the specified value. Note that valid values for this
498 * option are specific to a given operating system.
500 * @param size The new receive buffer size.
502 * @exception SocketException If an error occurs or Socket is not connected
503 * @exception IllegalArgumentException If size is 0 or negative
507 public void setReceiveBufferSize (int size)
508 throws SocketException
511 throw new SocketException ("Not connected");
514 throw new IllegalArgumentException ("SO_RCVBUF value must be > 0");
516 impl.setOption (SocketOptions.SO_RCVBUF, new Integer (size));
520 * This method returns the value of the system level socket option
521 * SO_RCVBUF, which is used by the operating system to tune buffer
522 * sizes for data transfers.
524 * @return The receive buffer size.
526 * @exception SocketException If an error occurs or Socket is not connected
530 public int getReceiveBufferSize ()
531 throws SocketException
534 throw new SocketException ("Not connected");
536 Object buf = impl.getOption (SocketOptions.SO_RCVBUF);
538 if (!(buf instanceof Integer))
539 throw new SocketException ("Internal Error: Unexpected type");
541 return ((Integer) buf).intValue ();
545 * Returns the value of this socket as a <code>String</code>.
547 * @return This socket represented as a <code>String</code>.
549 public String toString ()
551 return "ServerSocket" + impl.toString();
557 * Sets the <code>SocketImplFactory</code> for all
558 * <code>ServerSocket</code>'s. This may only be done
559 * once per virtual machine. Subsequent attempts will generate an
560 * exception. Note that a <code>SecurityManager</code> check is made prior
561 * to setting the factory. If insufficient privileges exist to set the
562 * factory, an exception will be thrown
564 * @exception SecurityException If this operation is not allowed by the
565 * <code>SecurityManager</code>.
566 * @exception SocketException If the factory object is already defined
567 * @exception IOException If any other error occurs
569 public static synchronized void setSocketFactory (SocketImplFactory fac)