Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / java / net / ServerSocket.java
blobb0576bf4cd506d8b0569845f3ae02e9cfe6b05f8
1 /* ServerSocket.java -- Class for implementing server side sockets
2 Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004
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., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307 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 * True if socket is bound.
81 private boolean bound;
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 bound = true;
243 catch (IOException exception)
245 close();
246 throw exception;
248 catch (RuntimeException exception)
250 close();
251 throw exception;
253 catch (Error error)
255 close();
256 throw error;
261 * This method returns the local address to which this socket is bound
263 * @return The socket's local address
265 public InetAddress getInetAddress()
267 if (! isBound())
268 return null;
272 return (InetAddress) impl.getOption(SocketOptions.SO_BINDADDR);
274 catch (SocketException e)
276 // This never happens as we are bound.
277 return null;
282 * This method returns the local port number to which this socket is bound
284 * @return The socket's port number
286 public int getLocalPort()
288 if (! isBound())
289 return -1;
291 return impl.getLocalPort();
295 * Returns the local socket address
297 * @return the local socket address, null if not bound
299 * @since 1.4
301 public SocketAddress getLocalSocketAddress()
303 if (! isBound())
304 return null;
306 return new InetSocketAddress(getInetAddress(), getLocalPort());
310 * Accepts a new connection and returns a connected <code>Socket</code>
311 * instance representing that connection. This method will block until a
312 * connection is available.
314 * @return socket object for the just accepted connection
316 * @exception IOException If an error occurs
317 * @exception SecurityException If a security manager exists and its
318 * checkListen method doesn't allow the operation
319 * @exception IllegalBlockingModeException If this socket has an associated
320 * channel, and the channel is in non-blocking mode
321 * @exception SocketTimeoutException If a timeout was previously set with
322 * setSoTimeout and the timeout has been reached
324 public Socket accept() throws IOException
326 SecurityManager sm = System.getSecurityManager();
327 if (sm != null)
328 sm.checkListen(impl.getLocalPort());
330 Socket socket = new Socket();
334 implAccept(socket);
336 catch (IOException e)
340 socket.close();
342 catch (IOException e2)
344 // Ignore.
347 throw e;
350 return socket;
354 * This protected method is used to help subclasses override
355 * <code>ServerSocket.accept()</code>. The passed in socket will be
356 * connected when this method returns.
358 * @param socket The socket that is used for the accepted connection
360 * @exception IOException If an error occurs
361 * @exception IllegalBlockingModeException If this socket has an associated
362 * channel, and the channel is in non-blocking mode
364 * @since 1.1
366 protected final void implAccept(Socket socket) throws IOException
368 if (isClosed())
369 throw new SocketException("ServerSocket is closed");
371 // The Sun spec says that if we have an associated channel and
372 // it is in non-blocking mode, we throw an IllegalBlockingModeException.
373 // However, in our implementation if the channel itself initiated this
374 // operation, then we must honor it regardless of its blocking mode.
375 if (getChannel() != null && ! getChannel().isBlocking()
376 && ! ((PlainSocketImpl) getImpl()).isInChannelOperation())
377 throw new IllegalBlockingModeException();
379 impl.accept(socket.impl);
380 socket.implCreated = true;
384 * Closes this socket and stops listening for connections
386 * @exception IOException If an error occurs
388 public void close() throws IOException
390 if (isClosed())
391 return;
393 impl.close();
394 impl = null;
395 bound = false;
397 if (getChannel() != null)
398 getChannel().close();
402 * Returns the unique ServerSocketChannel object
403 * associated with this socket, if any.
405 * The socket only has a ServerSocketChannel if its created
406 * by ServerSocketChannel.open.
408 * @return the associated socket channel, null if none exists
410 * @since 1.4
412 public ServerSocketChannel getChannel()
414 return null;
418 * Returns true when the socket is bound, otherwise false
420 * @return true if socket is bound, false otherwise
422 * @since 1.4
424 public boolean isBound()
426 return bound;
430 * Returns true if the socket is closed, otherwise false
432 * @return true if socket is closed, false otherwise
434 * @since 1.4
436 public boolean isClosed()
438 return impl == null;
442 * Sets the value of SO_TIMEOUT. A value of 0 implies that SO_TIMEOUT is
443 * disabled (ie, operations never time out). This is the number of
444 * milliseconds a socket operation can block before an
445 * InterruptedIOException is thrown.
447 * @param timeout The new SO_TIMEOUT value
449 * @exception SocketException If an error occurs
451 * @since 1.1
453 public void setSoTimeout(int timeout) throws SocketException
455 if (isClosed())
456 throw new SocketException("ServerSocket is closed");
458 if (timeout < 0)
459 throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
461 impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
465 * Retrieves the current value of the SO_TIMEOUT setting. A value of 0
466 * implies that SO_TIMEOUT is disabled (ie, operations never time out).
467 * This is the number of milliseconds a socket operation can block before
468 * an InterruptedIOException is thrown.
470 * @return The value of SO_TIMEOUT
472 * @exception IOException If an error occurs
474 * @since 1.1
476 public int getSoTimeout() throws IOException
478 if (isClosed())
479 throw new SocketException("ServerSocket is closed");
481 Object timeout = impl.getOption(SocketOptions.SO_TIMEOUT);
483 if (! (timeout instanceof Integer))
484 throw new IOException("Internal Error");
486 return ((Integer) timeout).intValue();
490 * Enables/Disables the SO_REUSEADDR option
492 * @param on true if SO_REUSEADDR should be enabled, false otherwise
494 * @exception SocketException If an error occurs
496 * @since 1.4
498 public void setReuseAddress(boolean on) throws SocketException
500 if (isClosed())
501 throw new SocketException("ServerSocket is closed");
503 impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
507 * Checks if the SO_REUSEADDR option is enabled
509 * @return true if SO_REUSEADDR is set, false otherwise
511 * @exception SocketException If an error occurs
513 * @since 1.4
515 public boolean getReuseAddress() throws SocketException
517 if (isClosed())
518 throw new SocketException("ServerSocket is closed");
520 Object reuseaddr = impl.getOption(SocketOptions.SO_REUSEADDR);
522 if (! (reuseaddr instanceof Boolean))
523 throw new SocketException("Internal Error");
525 return ((Boolean) reuseaddr).booleanValue();
529 * This method sets the value for the system level socket option
530 * SO_RCVBUF to the specified value. Note that valid values for this
531 * option are specific to a given operating system.
533 * @param size The new receive buffer size.
535 * @exception SocketException If an error occurs or Socket is not connected
536 * @exception IllegalArgumentException If size is 0 or negative
538 * @since 1.4
540 public void setReceiveBufferSize(int size) throws SocketException
542 if (isClosed())
543 throw new SocketException("ServerSocket is closed");
545 if (size <= 0)
546 throw new IllegalArgumentException("SO_RCVBUF value must be > 0");
548 impl.setOption(SocketOptions.SO_RCVBUF, new Integer(size));
552 * This method returns the value of the system level socket option
553 * SO_RCVBUF, which is used by the operating system to tune buffer
554 * sizes for data transfers.
556 * @return The receive buffer size.
558 * @exception SocketException If an error occurs or Socket is not connected
560 * @since 1.4
562 public int getReceiveBufferSize() throws SocketException
564 if (isClosed())
565 throw new SocketException("ServerSocket is closed");
567 Object buf = impl.getOption(SocketOptions.SO_RCVBUF);
569 if (! (buf instanceof Integer))
570 throw new SocketException("Internal Error: Unexpected type");
572 return ((Integer) buf).intValue();
576 * Returns the value of this socket as a <code>String</code>.
578 * @return This socket represented as a <code>String</code>.
580 public String toString()
582 if (! isBound())
583 return "ServerSocket[unbound]";
585 return ("ServerSocket[addr=" + getInetAddress() + ",port="
586 + impl.getPort() + ",localport=" + impl.getLocalPort() + "]");
590 * Sets the <code>SocketImplFactory</code> for all
591 * <code>ServerSocket</code>'s. This may only be done
592 * once per virtual machine. Subsequent attempts will generate an
593 * exception. Note that a <code>SecurityManager</code> check is made prior
594 * to setting the factory. If insufficient privileges exist to set the
595 * factory, an exception will be thrown
597 * @param fac the factory to set
599 * @exception SecurityException If this operation is not allowed by the
600 * <code>SecurityManager</code>.
601 * @exception SocketException If the factory object is already defined
602 * @exception IOException If any other error occurs
604 public static synchronized void setSocketFactory(SocketImplFactory fac)
605 throws IOException
607 factory = fac;