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
67 * This is the user defined SocketImplFactory, if one is supplied
69 private static SocketImplFactory factory;
74 * This is the SocketImp object to which most instance methods in this
75 * class are redirected
77 private SocketImpl impl;
80 * ServerSocketChannel of this ServerSocket. This channel only exists
81 * when the socket is created by ServerSocketChannel.open().
83 private ServerSocketChannel ch;
86 * Constructor that simply sets the implementation.
88 * @exception IOException If an error occurs
90 * @specnote This constructor is public since JDK 1.4
92 public ServerSocket() throws IOException
95 impl = factory.createSocketImpl();
97 impl = new PlainSocketImpl();
101 * Creates a server socket and binds it to the specified port. If the
102 * port number is 0, a random free port will be chosen. The pending
103 * connection queue on this socket will be set to 50.
105 * @param port The port number to bind to
107 * @exception IOException If an error occurs
108 * @exception SecurityException If a security manager exists and its
109 * checkListen method doesn't allow the operation
111 public ServerSocket (int port)
118 * Creates a server socket and binds it to the specified port. If the
119 * port number is 0, a random free port will be chosen. The pending
120 * connection queue on this socket will be set to the value passed as
123 * @param port The port number to bind to
124 * @param backlog The length of the pending connection queue
126 * @exception IOException If an error occurs
127 * @exception SecurityException If a security manager exists and its
128 * checkListen method doesn't allow the operation
130 public ServerSocket (int port, int backlog)
133 this(port, backlog, null);
137 * Creates a server socket and binds it to the specified port. If the
138 * port number is 0, a random free port will be chosen. The pending
139 * connection queue on this socket will be set to the value passed as
140 * backlog. The third argument specifies a particular local address to
141 * bind t or null to bind to all local address.
143 * @param port The port number to bind to
144 * @param backlog The length of the pending connection queue
145 * @param bindAddr The address to bind to, or null to bind to all addresses
147 * @exception IOException If an error occurs
148 * @exception SecurityException If a security manager exists and its
149 * checkListen method doesn't allow the operation
153 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;
168 impl.bind(bindAddr, port);
169 impl.listen(backlog);
173 * Binds the server socket to a specified socket address
175 * @param endpoint The socket address to bind to
177 * @exception IOException If an error occurs
178 * @exception IllegalArgumentException If address type is not supported
179 * @exception SecurityException If a security manager exists and its
180 * checkListen method doesn't allow the operation
184 public void bind (SocketAddress endpoint)
188 throw new IOException ("Cannot initialize Socket implementation");
190 if (! (endpoint instanceof InetSocketAddress))
191 throw new IllegalArgumentException ("Address type not supported");
193 InetSocketAddress tmp = (InetSocketAddress) endpoint;
195 SecurityManager s = System.getSecurityManager ();
197 s.checkListen (tmp.getPort ());
199 impl.bind (tmp.getAddress (), tmp.getPort ());
203 * Binds the server socket to a specified socket address
205 * @param endpoint The socket address to bind to
206 * @param backlog The length of the pending connection queue
208 * @exception IOException If an error occurs
209 * @exception IllegalArgumentException If address type is not supported
210 * @exception SecurityException If a security manager exists and its
211 * checkListen method doesn't allow the operation
215 public void bind (SocketAddress endpoint, int backlog) throws IOException
218 throw new IOException ("Cannot initialize Socket implementation");
220 if (! (endpoint instanceof InetSocketAddress))
221 throw new IllegalArgumentException ("Address type not supported");
223 InetSocketAddress tmp = (InetSocketAddress) endpoint;
225 SecurityManager s = System.getSecurityManager ();
227 s.checkListen (tmp.getPort ());
229 impl.bind (tmp.getAddress (), tmp.getPort ());
230 impl.listen(backlog);
234 * This method returns the local address to which this socket is bound
236 * @return The socket's local address
238 public InetAddress getInetAddress()
242 return (InetAddress) impl.getOption (SocketOptions.SO_BINDADDR);
244 catch (SocketException e)
251 * This method returns the local port number to which this socket is bound
253 * @return The socket's port number
255 public int getLocalPort()
257 return impl.getLocalPort();
261 * Returns the local socket address
265 public SocketAddress getLocalSocketAddress()
267 InetAddress addr = getInetAddress();
270 return new InetSocketAddress (getInetAddress(), getLocalPort());
276 * Accepts a new connection and returns a connected <code>Socket</code>
277 * instance representing that connection. This method will block until a
278 * connection is available.
280 * @exception IOException If an error occurs
281 * @exception SecurityException If a security manager exists and its
282 * checkListen method doesn't allow the operation
283 * @exception IllegalBlockingModeException If this socket has an associated
284 * channel, and the channel is in non-blocking mode
285 * @exception SocketTimeoutException If a timeout was previously set with
286 * setSoTimeout and the timeout has been reached
288 public Socket accept () throws IOException
290 Socket s = new Socket();
297 * This protected method is used to help subclasses override
298 * <code>ServerSocket.accept()</code>. The passed in socket will be
299 * connected when this method returns.
301 * @param socket The socket that is used for the accepted connection
303 * @exception IOException If an error occurs
304 * @exception IllegalBlockingModeException If this socket has an associated
305 * channel, and the channel is in non-blocking mode
309 protected final void implAccept (Socket s)
312 if (ch != null && !ch.isBlocking())
313 throw new IllegalBlockingModeException();
319 * Closes this socket and stops listening for connections
321 * @exception IOException If an error occurs
323 public void close () throws IOException
329 * Returns the unique ServerSocketChannel object
330 * associated with this socket, if any.
332 * The socket only has a ServerSocketChannel if its created
333 * by ServerSocketChannel.open.
337 public ServerSocketChannel getChannel()
343 * Returns true then the socket is bound, otherwise false
347 public boolean isBound()
351 Object bindaddr = impl.getOption (SocketOptions.SO_BINDADDR);
353 catch (SocketException e)
362 * Sets the value of SO_TIMEOUT. A value of 0 implies that SO_TIMEOUT is
363 * disabled (ie, operations never time out). This is the number of
364 * milliseconds a socket operation can block before an
365 * InterruptedIOException is thrown.
367 * @param timeout The new SO_TIMEOUT value
369 * @exception SocketException If an error occurs
373 public void setSoTimeout (int timeout) throws SocketException
376 throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
378 impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
382 * Retrieves the current value of the SO_TIMEOUT setting. A value of 0
383 * implies that SO_TIMEOUT is disabled (ie, operations never time out).
384 * This is the number of milliseconds a socket operation can block before
385 * an InterruptedIOException is thrown.
387 * @return The value of SO_TIMEOUT
389 * @exception IOException If an error occurs
393 public int getSoTimeout () throws IOException
395 Object timeout = impl.getOption(SocketOptions.SO_TIMEOUT);
397 if (!(timeout instanceof Integer))
398 throw new IOException("Internal Error");
400 return ((Integer)timeout).intValue();
404 * Enables/Disables the SO_REUSEADDR option
406 * @exception SocketException If an error occurs
410 public void setReuseAddress (boolean on)
411 throws SocketException
414 throw new SocketException ("Cannot initialize Socket implementation");
416 impl.setOption (SocketOptions.SO_REUSEADDR, new Boolean (on));
420 * Checks if the SO_REUSEADDR option is enabled
422 * @exception SocketException If an error occurs
426 public boolean getReuseAddress()
427 throws SocketException
430 throw new SocketException ("Cannot initialize Socket implementation");
432 Object reuseaddr = impl.getOption (SocketOptions.SO_REUSEADDR);
434 if (!(reuseaddr instanceof Boolean))
435 throw new SocketException ("Internal Error");
437 return ((Boolean) reuseaddr).booleanValue ();
441 * This method sets the value for the system level socket option
442 * SO_RCVBUF to the specified value. Note that valid values for this
443 * option are specific to a given operating system.
445 * @param size The new receive buffer size.
447 * @exception SocketException If an error occurs or Socket is not connected
448 * @exception IllegalArgumentException If size is 0 or negative
452 public void setReceiveBufferSize (int size)
453 throws SocketException
456 throw new SocketException ("Not connected");
459 throw new IllegalArgumentException ("SO_RCVBUF value must be > 0");
461 impl.setOption (SocketOptions.SO_RCVBUF, new Integer (size));
465 * This method returns the value of the system level socket option
466 * SO_RCVBUF, which is used by the operating system to tune buffer
467 * sizes for data transfers.
469 * @return The receive buffer size.
471 * @exception SocketException If an error occurs or Socket is not connected
475 public int getReceiveBufferSize ()
476 throws SocketException
479 throw new SocketException ("Not connected");
481 Object buf = impl.getOption (SocketOptions.SO_RCVBUF);
483 if (!(buf instanceof Integer))
484 throw new SocketException ("Internal Error: Unexpected type");
486 return ((Integer) buf).intValue ();
490 * Returns the value of this socket as a <code>String</code>.
492 * @return This socket represented as a <code>String</code>.
494 public String toString ()
496 return "ServerSocket" + impl.toString();
502 * Sets the <code>SocketImplFactory</code> for all
503 * <code>ServerSocket</code>'s. This may only be done
504 * once per virtual machine. Subsequent attempts will generate an
505 * exception. Note that a <code>SecurityManager</code> check is made prior
506 * to setting the factory. If insufficient privileges exist to set the
507 * factory, an exception will be thrown
509 * @exception SecurityException If this operation is not allowed by the
510 * <code>SecurityManager</code>.
511 * @exception SocketException If the factory object is already defined
512 * @exception IOException If any other error occurs
514 public static synchronized void setSocketFactory (SocketImplFactory fac)