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)
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
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
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. */
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.
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
68 * This is the user defined SocketImplFactory, if one is supplied
70 private static SocketImplFactory factory
;
73 * This is the SocketImp object to which most instance methods in this
74 * class are redirected
76 private SocketImpl impl
;
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
92 throw new NullPointerException("impl may not be null");
95 this.impl
.create(true);
99 * This method is only used by java.nio.
102 // FIXME: Workaround a bug in gcj.
103 //PlainSocketImpl getImpl()
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
119 impl
= factory
.createSocketImpl();
121 impl
= new PlainSocketImpl();
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
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
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
177 public ServerSocket(int port
, int backlog
, InetAddress bindAddr
)
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
198 public void bind(SocketAddress endpoint
) throws IOException
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
216 public void bind(SocketAddress endpoint
, int backlog
)
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();
229 s
.checkListen(tmp
.getPort());
231 InetAddress addr
= tmp
.getAddress();
233 // Initialize addr with 0.0.0.0.
235 addr
= InetAddress
.ANY_IF
;
239 impl
.bind(addr
, tmp
.getPort());
240 impl
.listen(backlog
);
243 catch (IOException exception
)
248 catch (RuntimeException exception
)
261 * This method returns the local address to which this socket is bound
263 * @return The socket's local address
265 public InetAddress
getInetAddress()
272 return (InetAddress
) impl
.getOption(SocketOptions
.SO_BINDADDR
);
274 catch (SocketException e
)
276 // This never happens as we are bound.
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()
291 return impl
.getLocalPort();
295 * Returns the local socket address
297 * @return the local socket address, null if not bound
301 public SocketAddress
getLocalSocketAddress()
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();
328 sm
.checkListen(impl
.getLocalPort());
330 Socket socket
= new Socket();
336 catch (IOException e
)
342 catch (IOException e2
)
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
366 protected final void implAccept(Socket socket
) throws IOException
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
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
412 public ServerSocketChannel
getChannel()
418 * Returns true when the socket is bound, otherwise false
420 * @return true if socket is bound, false otherwise
424 public boolean isBound()
430 * Returns true if the socket is closed, otherwise false
432 * @return true if socket is closed, false otherwise
436 public boolean isClosed()
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
453 public void setSoTimeout(int timeout
) throws SocketException
456 throw new SocketException("ServerSocket is closed");
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
476 public int getSoTimeout() throws IOException
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
498 public void setReuseAddress(boolean on
) throws SocketException
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
515 public boolean getReuseAddress() throws SocketException
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
540 public void setReceiveBufferSize(int size
) throws SocketException
543 throw new SocketException("ServerSocket is closed");
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
562 public int getReceiveBufferSize() throws SocketException
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()
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
)