Merge from mainline
[official-gcc.git] / libjava / classpath / java / net / ServerSocket.java
blob2b889531a7c18c332b36c6bdfb388ae24dd6379d
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)
10 any later version.
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
20 02110-1301 USA.
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
25 combination.
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. */
39 package java.net;
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.
52 /**
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
67 /**
68 * This is the user defined SocketImplFactory, if one is supplied
70 private static SocketImplFactory factory;
72 /**
73 * This is the SocketImp object to which most instance methods in this
74 * class are redirected
76 private SocketImpl impl;
78 /**
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
91 if (impl == null)
92 throw new NullPointerException("impl may not be null");
94 this.impl = impl;
95 this.impl.create(true);
99 * This method is only used by java.nio.
102 // FIXME: Workaround a bug in gcj.
103 //PlainSocketImpl getImpl()
104 SocketImpl getImpl()
106 return impl;
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
118 if (factory != null)
119 impl = factory.createSocketImpl();
120 else
121 impl = new PlainSocketImpl();
123 impl.create(true);
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
139 this(port, 50);
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
146 * arg2.
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
175 * @since 1.1
177 public ServerSocket(int port, int backlog, InetAddress bindAddr)
178 throws IOException
180 this();
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
196 * @since 1.4
198 public void bind(SocketAddress endpoint) throws IOException
200 bind(endpoint, 50);
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
214 * @since 1.4
216 public void bind(SocketAddress endpoint, int backlog)
217 throws IOException
219 if (isClosed())
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();
228 if (s != null)
229 s.checkListen(tmp.getPort());
231 InetAddress addr = tmp.getAddress();
233 // Initialize addr with 0.0.0.0.
234 if (addr == null)
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)
247 close();
248 throw exception;
250 catch (RuntimeException exception)
252 close();
253 throw exception;
255 catch (Error error)
257 close();
258 throw error;
263 * This method returns the local address to which this socket is bound
265 * @return The socket's local address
267 public InetAddress getInetAddress()
269 if (local == null)
270 return null;
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()
282 if (local == null)
283 return -1;
285 return local.getPort();
289 * Returns the local socket address
291 * @return the local socket address, null if not bound
293 * @since 1.4
295 public SocketAddress getLocalSocketAddress()
297 return local;
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();
321 implAccept(socket);
323 catch (IOException e)
327 socket.close();
329 catch (IOException e2)
331 // Ignore.
334 throw e;
337 return socket;
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
351 * @since 1.1
353 protected final void implAccept(Socket socket) throws IOException
355 if (isClosed())
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;
371 socket.bound = true;
375 * Closes this socket and stops listening for connections
377 * @exception IOException If an error occurs
379 public void close() throws IOException
381 if (isClosed())
382 return;
384 impl.close();
385 impl = null;
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
400 * @since 1.4
402 public ServerSocketChannel getChannel()
404 return null;
408 * Returns true when the socket is bound, otherwise false
410 * @return true if socket is bound, false otherwise
412 * @since 1.4
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
424 * @since 1.4
426 public boolean isClosed()
428 return impl == null;
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
441 * @since 1.1
443 public void setSoTimeout(int timeout) throws SocketException
445 if (isClosed())
446 throw new SocketException("ServerSocket is closed");
448 if (timeout < 0)
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
464 * @since 1.1
466 public int getSoTimeout() throws IOException
468 if (isClosed())
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
486 * @since 1.4
488 public void setReuseAddress(boolean on) throws SocketException
490 if (isClosed())
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
503 * @since 1.4
505 public boolean getReuseAddress() throws SocketException
507 if (isClosed())
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
528 * @since 1.4
530 public void setReceiveBufferSize(int size) throws SocketException
532 if (isClosed())
533 throw new SocketException("ServerSocket is closed");
535 if (size <= 0)
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
550 * @since 1.4
552 public int getReceiveBufferSize() throws SocketException
554 if (isClosed())
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()
572 if (! isBound())
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)
595 throws IOException
597 factory = fac;