Merged gcj-eclipse branch to trunk.
[official-gcc.git] / libjava / classpath / java / net / ServerSocket.java
blobd5f2a176b812160fd592f9832613a330dd61cebb
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;
82 private int port;
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
92 if (impl == null)
93 throw new NullPointerException("impl may not be null");
95 this.impl = impl;
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()
106 SocketImpl getImpl()
108 return impl;
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
120 if (factory != null)
121 impl = factory.createSocketImpl();
122 else
123 impl = new PlainSocketImpl();
125 impl.create(true);
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
141 this(port, 50);
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
148 * arg2.
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
177 * @since 1.1
179 public ServerSocket(int port, int backlog, InetAddress bindAddr)
180 throws IOException
182 this();
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
198 * @since 1.4
200 public void bind(SocketAddress endpoint) throws IOException
202 bind(endpoint, 50);
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
216 * @since 1.4
218 public void bind(SocketAddress endpoint, int backlog)
219 throws IOException
221 if (isClosed())
222 throw new SocketException("ServerSocket is closed");
224 if (isBound())
225 throw new SocketException("Already bound");
227 InetAddress addr;
228 int port;
230 if (endpoint == null)
232 addr = InetAddress.ANY_IF;
233 port = 0;
235 else if (! (endpoint instanceof InetSocketAddress))
237 throw new IllegalArgumentException("Address type not supported");
239 else
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();
249 if (s != null)
250 s.checkListen(port);
254 impl.bind(addr, port);
255 impl.listen(backlog);
256 this.port = port;
257 local = new InetSocketAddress(
258 (InetAddress) impl.getOption(SocketOptions.SO_BINDADDR),
259 impl.getLocalPort());
261 finally
265 if (local == null)
266 close();
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()
281 if (local == null)
282 return null;
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()
294 if (local == null)
295 return -1;
297 return local.getPort();
301 * Returns the local socket address
303 * @return the local socket address, null if not bound
305 * @since 1.4
307 public SocketAddress getLocalSocketAddress()
309 return local;
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();
333 implAccept(socket);
335 catch (IOException e)
339 socket.close();
341 catch (IOException e2)
343 // Ignore.
346 throw e;
348 catch (SecurityException e)
352 socket.close();
354 catch (IOException e2)
356 // Ignore.
359 throw e;
362 return socket;
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
376 * @since 1.1
378 protected final void implAccept(Socket socket) throws IOException
380 if (isClosed())
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);
392 socket.bound = true;
394 SecurityManager sm = System.getSecurityManager();
395 if (sm != null)
396 sm.checkAccept(socket.getInetAddress().getHostAddress(),
397 socket.getPort());
401 * Closes this socket and stops listening for connections
403 * @exception IOException If an error occurs
405 public void close() throws IOException
407 if (impl != null)
409 impl.close();
410 impl = null;
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
423 * @since 1.4
425 public ServerSocketChannel getChannel()
427 return null;
431 * Returns true when the socket is bound, otherwise false
433 * @return true if socket is bound, false otherwise
435 * @since 1.4
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
447 * @since 1.4
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
465 * @since 1.1
467 public void setSoTimeout(int timeout) throws SocketException
469 if (isClosed())
470 throw new SocketException("ServerSocket is closed");
472 if (timeout < 0)
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
488 * @since 1.1
490 public int getSoTimeout() throws IOException
492 if (isClosed())
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
510 * @since 1.4
512 public void setReuseAddress(boolean on) throws SocketException
514 if (isClosed())
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
527 * @since 1.4
529 public boolean getReuseAddress() throws SocketException
531 if (isClosed())
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
552 * @since 1.4
554 public void setReceiveBufferSize(int size) throws SocketException
556 if (isClosed())
557 throw new SocketException("ServerSocket is closed");
559 if (size <= 0)
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
574 * @since 1.4
576 public int getReceiveBufferSize() throws SocketException
578 if (isClosed())
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()
596 if (! isBound())
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)
619 throws IOException
621 if (factory != null)
622 throw new SocketException("SocketFactory already defined");
624 SecurityManager sm = System.getSecurityManager();
625 if (sm != null)
626 sm.checkSetFactory();
628 factory = fac;