OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / java / net / ServerSocket.java
1 /* ServerSocket.java -- Class for implementing server side sockets
2    Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2006
3    Free Software Foundation, Inc.
4
5 This file is part of GNU Classpath.
6
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.
11
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.
16
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.
21
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.
26
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. */
38
39 package java.net;
40
41 import gnu.java.net.PlainSocketImpl;
42
43 import java.io.IOException;
44 import java.nio.channels.IllegalBlockingModeException;
45 import java.nio.channels.ServerSocketChannel;
46
47
48 /* Written using on-line Java Platform 1.2 API Specification.
49  * Status:  I believe all methods are implemented.
50  */
51
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.
58  *
59  * As with the <code>Socket</code> class, most instance methods of this class
60  * simply redirect their calls to an implementation class.
61  *
62  * @author Aaron M. Renn (arenn@urbanophile.com)
63  * @author Per Bothner (bothner@cygnus.com)
64  */
65 public class ServerSocket
66 {
67   /**
68    * This is the user defined SocketImplFactory, if one is supplied
69    */
70   private static SocketImplFactory factory;
71
72   /**
73    * This is the SocketImp object to which most instance methods in this
74    * class are redirected
75    */
76   private SocketImpl impl;
77
78   /**
79    * We need to retain the local address even after the socket is closed.
80    */
81   private InetSocketAddress local;
82   private int port;
83
84   /*
85    * This constructor is only used by java.nio.
86    */
87
88   // FIXME: Workaround a bug in gcj.
89   //ServerSocket (PlainSocketImpl impl) throws IOException
90   ServerSocket(SocketImpl impl) throws IOException
91   {
92     if (impl == null)
93       throw new NullPointerException("impl may not be null");
94
95     this.impl = impl;
96     this.impl.create(true);
97     setReuseAddress(true);
98   }
99
100   /*
101    * This method is only used by java.nio.
102    */
103
104   // FIXME: Workaround a bug in gcj.
105   //PlainSocketImpl getImpl()
106   SocketImpl getImpl()
107   {
108     return impl;
109   }
110
111   /**
112    * Constructor that simply sets the implementation.
113    *
114    * @exception IOException If an error occurs
115    *
116    * @specnote This constructor is public since JDK 1.4
117    */
118   public ServerSocket() throws IOException
119   {
120     if (factory != null)
121       impl = factory.createSocketImpl();
122     else
123       impl = new PlainSocketImpl();
124
125     impl.create(true);
126   }
127
128   /**
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.
132    *
133    * @param port The port number to bind to
134    *
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
138    */
139   public ServerSocket(int port) throws IOException
140   {
141     this(port, 50);
142   }
143
144   /**
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.
149    *
150    * @param port The port number to bind to
151    * @param backlog The length of the pending connection queue
152    *
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
156    */
157   public ServerSocket(int port, int backlog) throws IOException
158   {
159     this(port, backlog, null);
160   }
161
162   /**
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.
168    *
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
172    *
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
176    *
177    * @since 1.1
178    */
179   public ServerSocket(int port, int backlog, InetAddress bindAddr)
180     throws IOException
181   {
182     this();
183
184     // bind/listen socket
185     bind(new InetSocketAddress(bindAddr, port), backlog);
186   }
187
188   /**
189    * Binds the server socket to a specified socket address
190    *
191    * @param endpoint The socket address to bind to
192    *
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
197    *
198    * @since 1.4
199    */
200   public void bind(SocketAddress endpoint) throws IOException
201   {
202     bind(endpoint, 50);
203   }
204
205   /**
206    * Binds the server socket to a specified socket address
207    *
208    * @param endpoint The socket address to bind to
209    * @param backlog The length of the pending connection queue
210    *
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
215    *
216    * @since 1.4
217    */
218   public void bind(SocketAddress endpoint, int backlog)
219     throws IOException
220   {
221     if (isClosed())
222       throw new SocketException("ServerSocket is closed");
223
224     if (isBound())
225       throw new SocketException("Already bound");
226
227     InetAddress addr;
228     int port;
229
230     if (endpoint == null)
231       {
232         addr = InetAddress.ANY_IF;
233         port = 0;
234       }
235     else if (! (endpoint instanceof InetSocketAddress))
236       {
237         throw new IllegalArgumentException("Address type not supported");
238       }
239     else
240       {
241         InetSocketAddress tmp = (InetSocketAddress) endpoint;
242         if (tmp.isUnresolved())
243           throw new SocketException("Unresolved address");
244         addr = tmp.getAddress();
245         port = tmp.getPort();
246       }
247
248     SecurityManager s = System.getSecurityManager();
249     if (s != null)
250       s.checkListen(port);
251
252     try
253       {
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());
260       }
261     finally
262       {
263         try
264           {
265             if (local == null)
266               close();
267           }
268         catch (IOException _)
269           {
270           }
271       }
272   }
273
274   /**
275    * This method returns the local address to which this socket is bound
276    *
277    * @return The socket's local address
278    */
279   public InetAddress getInetAddress()
280   {
281     if (local == null)
282       return null;
283
284     return local.getAddress();
285   }
286
287   /**
288    * This method returns the local port number to which this socket is bound
289    *
290    * @return The socket's port number
291    */
292   public int getLocalPort()
293   {
294     if (local == null)
295       return -1;
296
297     return local.getPort();
298   }
299
300   /**
301    * Returns the local socket address
302    *
303    * @return the local socket address, null if not bound
304    * 
305    * @since 1.4
306    */
307   public SocketAddress getLocalSocketAddress()
308   {
309     return local;
310   }
311
312   /**
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.
316    *
317    * @return socket object for the just accepted connection
318    *
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
326    */
327   public Socket accept() throws IOException
328   {
329     Socket socket = new Socket();
330
331     try
332       {
333         implAccept(socket);
334       }
335     catch (IOException e)
336       {
337         try
338           {
339             socket.close();
340           }
341         catch (IOException e2)
342           {
343             // Ignore.
344           }
345
346         throw e;
347       }
348     catch (SecurityException e)
349       {
350         try
351           {
352             socket.close();
353           }
354         catch (IOException e2)
355           {
356             // Ignore.
357           }
358
359         throw e;
360       }
361
362     return socket;
363   }
364
365   /**
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.
369    *
370    * @param socket The socket that is used for the accepted connection
371    *
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
375    *
376    * @since 1.1
377    */
378   protected final void implAccept(Socket socket) throws IOException
379   {
380     if (isClosed())
381       throw new SocketException("ServerSocket is closed");
382
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();
390
391     impl.accept(socket.impl);
392     socket.bound = true;
393
394     SecurityManager sm = System.getSecurityManager();
395     if (sm != null)
396       sm.checkAccept(socket.getInetAddress().getHostAddress(),
397                      socket.getPort());
398   }
399
400   /**
401    * Closes this socket and stops listening for connections
402    *
403    * @exception IOException If an error occurs
404    */
405   public void close() throws IOException
406   {
407     if (impl != null)
408       {
409         impl.close();
410         impl = null;
411       }
412   }
413
414   /**
415    * Returns the unique <code>ServerSocketChannel</code> object
416    * associated with this socket, if any.
417    *
418    * <p>The socket only has a <code>ServerSocketChannel</code> if its created
419    * by <code>ServerSocketChannel.open()</code>.</p>
420    *
421    * @return the associated socket channel, null if none exists
422    * 
423    * @since 1.4
424    */
425   public ServerSocketChannel getChannel()
426   {
427     return null;
428   }
429
430   /**
431    * Returns true when the socket is bound, otherwise false
432    *
433    * @return true if socket is bound, false otherwise
434    * 
435    * @since 1.4
436    */
437   public boolean isBound()
438   {
439     return local != null;
440   }
441
442   /**
443    * Returns true if the socket is closed, otherwise false
444    *
445    * @return true if socket is closed, false otherwise
446    * 
447    * @since 1.4
448    */
449   public boolean isClosed()
450   {
451     ServerSocketChannel channel = getChannel();
452     return impl == null || (channel != null && ! channel.isOpen());
453   }
454
455   /**
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.
460    *
461    * @param timeout The new SO_TIMEOUT value
462    *
463    * @exception SocketException If an error occurs
464    *
465    * @since 1.1
466    */
467   public void setSoTimeout(int timeout) throws SocketException
468   {
469     if (isClosed())
470       throw new SocketException("ServerSocket is closed");
471
472     if (timeout < 0)
473       throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
474
475     impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
476   }
477
478   /**
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.
483    *
484    * @return The value of SO_TIMEOUT
485    *
486    * @exception IOException If an error occurs
487    *
488    * @since 1.1
489    */
490   public int getSoTimeout() throws IOException
491   {
492     if (isClosed())
493       throw new SocketException("ServerSocket is closed");
494
495     Object timeout = impl.getOption(SocketOptions.SO_TIMEOUT);
496
497     if (! (timeout instanceof Integer))
498       throw new IOException("Internal Error");
499
500     return ((Integer) timeout).intValue();
501   }
502
503   /**
504    * Enables/Disables the SO_REUSEADDR option
505    *
506    * @param on true if SO_REUSEADDR should be enabled, false otherwise
507    * 
508    * @exception SocketException If an error occurs
509    *
510    * @since 1.4
511    */
512   public void setReuseAddress(boolean on) throws SocketException
513   {
514     if (isClosed())
515       throw new SocketException("ServerSocket is closed");
516
517     impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
518   }
519
520   /**
521    * Checks if the SO_REUSEADDR option is enabled
522    *
523    * @return true if SO_REUSEADDR is set, false otherwise
524    *
525    * @exception SocketException If an error occurs
526    *
527    * @since 1.4
528    */
529   public boolean getReuseAddress() throws SocketException
530   {
531     if (isClosed())
532       throw new SocketException("ServerSocket is closed");
533
534     Object reuseaddr = impl.getOption(SocketOptions.SO_REUSEADDR);
535
536     if (! (reuseaddr instanceof Boolean))
537       throw new SocketException("Internal Error");
538
539     return ((Boolean) reuseaddr).booleanValue();
540   }
541
542   /**
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.
546    *
547    * @param size The new receive buffer size.
548    *
549    * @exception SocketException If an error occurs or Socket is not connected
550    * @exception IllegalArgumentException If size is 0 or negative
551    *
552    * @since 1.4
553    */
554   public void setReceiveBufferSize(int size) throws SocketException
555   {
556     if (isClosed())
557       throw new SocketException("ServerSocket is closed");
558
559     if (size <= 0)
560       throw new IllegalArgumentException("SO_RCVBUF value must be > 0");
561
562     impl.setOption(SocketOptions.SO_RCVBUF, new Integer(size));
563   }
564
565   /**
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.
569    *
570    * @return The receive buffer size.
571    *
572    * @exception SocketException If an error occurs or Socket is not connected
573    *
574    * @since 1.4
575    */
576   public int getReceiveBufferSize() throws SocketException
577   {
578     if (isClosed())
579       throw new SocketException("ServerSocket is closed");
580
581     Object buf = impl.getOption(SocketOptions.SO_RCVBUF);
582
583     if (! (buf instanceof Integer))
584       throw new SocketException("Internal Error: Unexpected type");
585
586     return ((Integer) buf).intValue();
587   }
588
589   /**
590    * Returns the value of this socket as a <code>String</code>.
591    *
592    * @return This socket represented as a <code>String</code>.
593    */
594   public String toString()
595   {
596     if (! isBound())
597       return "ServerSocket[unbound]";
598
599     return ("ServerSocket[addr=" + getInetAddress() + ",port="
600            + port + ",localport=" + getLocalPort() + "]");
601   }
602
603   /**
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
610    *
611    * @param fac the factory to set
612    *
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
617    */
618   public static synchronized void setSocketFactory(SocketImplFactory fac)
619     throws IOException
620   {
621     if (factory != null)
622       throw new SocketException("SocketFactory already defined");
623
624     SecurityManager sm = System.getSecurityManager();
625     if (sm != null)
626       sm.checkSetFactory();
627
628     factory = fac;
629   }
630 }