001    /* ServerSocket.java -- Class for implementing server side sockets
002       Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2006
003       Free Software Foundation, Inc.
004    
005    This file is part of GNU Classpath.
006    
007    GNU Classpath is free software; you can redistribute it and/or modify
008    it under the terms of the GNU General Public License as published by
009    the Free Software Foundation; either version 2, or (at your option)
010    any later version.
011    
012    GNU Classpath is distributed in the hope that it will be useful, but
013    WITHOUT ANY WARRANTY; without even the implied warranty of
014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015    General Public License for more details.
016    
017    You should have received a copy of the GNU General Public License
018    along with GNU Classpath; see the file COPYING.  If not, write to the
019    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
020    02110-1301 USA.
021    
022    Linking this library statically or dynamically with other modules is
023    making a combined work based on this library.  Thus, the terms and
024    conditions of the GNU General Public License cover the whole
025    combination.
026    
027    As a special exception, the copyright holders of this library give you
028    permission to link this library with independent modules to produce an
029    executable, regardless of the license terms of these independent
030    modules, and to copy and distribute the resulting executable under
031    terms of your choice, provided that you also meet, for each linked
032    independent module, the terms and conditions of the license of that
033    module.  An independent module is a module which is not derived from
034    or based on this library.  If you modify this library, you may extend
035    this exception to your version of the library, but you are not
036    obligated to do so.  If you do not wish to do so, delete this
037    exception statement from your version. */
038    
039    package java.net;
040    
041    import gnu.java.net.PlainSocketImpl;
042    
043    import java.io.IOException;
044    import java.nio.channels.IllegalBlockingModeException;
045    import java.nio.channels.ServerSocketChannel;
046    
047    
048    /* Written using on-line Java Platform 1.2 API Specification.
049     * Status:  I believe all methods are implemented.
050     */
051    
052    /**
053     * This class models server side sockets.  The basic model is that the
054     * server socket is created and bound to some well known port.  It then
055     * listens for and accepts connections.  At that point the client and
056     * server sockets are ready to communicate with one another utilizing
057     * whatever application layer protocol they desire.
058     *
059     * As with the <code>Socket</code> class, most instance methods of this class
060     * simply redirect their calls to an implementation class.
061     *
062     * @author Aaron M. Renn (arenn@urbanophile.com)
063     * @author Per Bothner (bothner@cygnus.com)
064     */
065    public class ServerSocket
066    {
067      /**
068       * This is the user defined SocketImplFactory, if one is supplied
069       */
070      private static SocketImplFactory factory;
071    
072      /**
073       * This is the SocketImp object to which most instance methods in this
074       * class are redirected
075       */
076      private SocketImpl impl;
077    
078      /**
079       * We need to retain the local address even after the socket is closed.
080       */
081      private InetSocketAddress local;
082      private int port;
083    
084      /*
085       * This constructor is only used by java.nio.
086       */
087    
088      ServerSocket(PlainSocketImpl impl) throws IOException
089      {
090        if (impl == null)
091          throw new NullPointerException("impl may not be null");
092    
093        this.impl = impl;
094        this.impl.create(true);
095        setReuseAddress(true);
096      }
097    
098      /*
099       * This method is only used by java.nio.
100       */
101    
102      SocketImpl getImpl()
103      {
104        return impl;
105      }
106    
107      /**
108       * Constructor that simply sets the implementation.
109       *
110       * @exception IOException If an error occurs
111       *
112       * @specnote This constructor is public since JDK 1.4
113       */
114      public ServerSocket() throws IOException
115      {
116        if (factory != null)
117          impl = factory.createSocketImpl();
118        else
119          impl = new PlainSocketImpl();
120    
121        impl.create(true);
122      }
123    
124      /**
125       * Creates a server socket and binds it to the specified port.  If the
126       * port number is 0, a random free port will be chosen.  The pending
127       * connection queue on this socket will be set to 50.
128       *
129       * @param port The port number to bind to
130       *
131       * @exception IOException If an error occurs
132       * @exception SecurityException If a security manager exists and its
133       * checkListen method doesn't allow the operation
134       */
135      public ServerSocket(int port) throws IOException
136      {
137        this(port, 50);
138      }
139    
140      /**
141       * Creates a server socket and binds it to the specified port.  If the
142       * port number is 0, a random free port will be chosen.  The pending
143       * connection queue on this socket will be set to the value passed as
144       * arg2.
145       *
146       * @param port The port number to bind to
147       * @param backlog The length of the pending connection queue
148       *
149       * @exception IOException If an error occurs
150       * @exception SecurityException If a security manager exists and its
151       * checkListen method doesn't allow the operation
152       */
153      public ServerSocket(int port, int backlog) throws IOException
154      {
155        this(port, backlog, null);
156      }
157    
158      /**
159       * Creates a server socket and binds it to the specified port.  If the
160       * port number is 0, a random free port will be chosen.  The pending
161       * connection queue on this socket will be set to the value passed as
162       * backlog.  The third argument specifies a particular local address to
163       * bind t or null to bind to all local address.
164       *
165       * @param port The port number to bind to
166       * @param backlog The length of the pending connection queue
167       * @param bindAddr The address to bind to, or null to bind to all addresses
168       *
169       * @exception IOException If an error occurs
170       * @exception SecurityException If a security manager exists and its
171       * checkListen method doesn't allow the operation
172       *
173       * @since 1.1
174       */
175      public ServerSocket(int port, int backlog, InetAddress bindAddr)
176        throws IOException
177      {
178        this();
179    
180        // bind/listen socket
181        bind(new InetSocketAddress(bindAddr, port), backlog);
182      }
183    
184      /**
185       * Binds the server socket to a specified socket address
186       *
187       * @param endpoint The socket address to bind to
188       *
189       * @exception IOException If an error occurs
190       * @exception IllegalArgumentException If address type is not supported
191       * @exception SecurityException If a security manager exists and its
192       * checkListen method doesn't allow the operation
193       *
194       * @since 1.4
195       */
196      public void bind(SocketAddress endpoint) throws IOException
197      {
198        bind(endpoint, 50);
199      }
200    
201      /**
202       * Binds the server socket to a specified socket address
203       *
204       * @param endpoint The socket address to bind to
205       * @param backlog The length of the pending connection queue
206       *
207       * @exception IOException If an error occurs
208       * @exception IllegalArgumentException If address type is not supported
209       * @exception SecurityException If a security manager exists and its
210       * checkListen method doesn't allow the operation
211       *
212       * @since 1.4
213       */
214      public void bind(SocketAddress endpoint, int backlog)
215        throws IOException
216      {
217        if (isClosed())
218          throw new SocketException("ServerSocket is closed");
219    
220        if (isBound())
221          throw new SocketException("Already bound");
222    
223        InetAddress addr;
224        int port;
225    
226        if (endpoint == null)
227          {
228            addr = InetAddress.ANY_IF;
229            port = 0;
230          }
231        else if (! (endpoint instanceof InetSocketAddress))
232          {
233            throw new IllegalArgumentException("Address type not supported");
234          }
235        else
236          {
237            InetSocketAddress tmp = (InetSocketAddress) endpoint;
238            if (tmp.isUnresolved())
239              throw new SocketException("Unresolved address");
240            addr = tmp.getAddress();
241            port = tmp.getPort();
242          }
243    
244        SecurityManager s = System.getSecurityManager();
245        if (s != null)
246          s.checkListen(port);
247    
248        try
249          {
250            impl.bind(addr, port);
251            impl.listen(backlog);
252            this.port = port;
253            local = new InetSocketAddress(
254                (InetAddress) impl.getOption(SocketOptions.SO_BINDADDR),
255                impl.getLocalPort());
256          }
257        finally
258          {
259            try
260              {
261                if (local == null)
262                  close();
263              }
264            catch (IOException _)
265              {
266              }
267          }
268      }
269    
270      /**
271       * This method returns the local address to which this socket is bound
272       *
273       * @return The socket's local address
274       */
275      public InetAddress getInetAddress()
276      {
277        if (local == null)
278          return null;
279    
280        return local.getAddress();
281      }
282    
283      /**
284       * This method returns the local port number to which this socket is bound
285       *
286       * @return The socket's port number
287       */
288      public int getLocalPort()
289      {
290        if (local == null)
291          return -1;
292    
293        return local.getPort();
294      }
295    
296      /**
297       * Returns the local socket address
298       *
299       * @return the local socket address, null if not bound
300       *
301       * @since 1.4
302       */
303      public SocketAddress getLocalSocketAddress()
304      {
305        return local;
306      }
307    
308      /**
309       * Accepts a new connection and returns a connected <code>Socket</code>
310       * instance representing that connection.  This method will block until a
311       * connection is available.
312       *
313       * @return socket object for the just accepted connection
314       *
315       * @exception IOException If an error occurs
316       * @exception SecurityException If a security manager exists and its
317       * checkListen method doesn't allow the operation
318       * @exception IllegalBlockingModeException If this socket has an associated
319       * channel, and the channel is in non-blocking mode
320       * @exception SocketTimeoutException If a timeout was previously set with
321       * setSoTimeout and the timeout has been reached
322       */
323      public Socket accept() throws IOException
324      {
325        Socket socket = new Socket();
326    
327        try
328          {
329            implAccept(socket);
330          }
331        catch (IOException e)
332          {
333            try
334              {
335                socket.close();
336              }
337            catch (IOException e2)
338              {
339                // Ignore.
340              }
341    
342            throw e;
343          }
344        catch (SecurityException e)
345          {
346            try
347              {
348                socket.close();
349              }
350            catch (IOException e2)
351              {
352                // Ignore.
353              }
354    
355            throw e;
356          }
357    
358        return socket;
359      }
360    
361      /**
362       * This protected method is used to help subclasses override
363       * <code>ServerSocket.accept()</code>.  The passed in socket will be
364       * connected when this method returns.
365       *
366       * @param socket The socket that is used for the accepted connection
367       *
368       * @exception IOException If an error occurs
369       * @exception IllegalBlockingModeException If this socket has an associated
370       * channel, and the channel is in non-blocking mode
371       *
372       * @since 1.1
373       */
374      protected final void implAccept(Socket socket) throws IOException
375      {
376        if (isClosed())
377          throw new SocketException("ServerSocket is closed");
378    
379        // The Sun spec says that if we have an associated channel and
380        // it is in non-blocking mode, we throw an IllegalBlockingModeException.
381        // However, in our implementation if the channel itself initiated this
382        // operation, then we must honor it regardless of its blocking mode.
383        if (getChannel() != null && ! getChannel().isBlocking()
384            && ! ((PlainSocketImpl) getImpl()).isInChannelOperation())
385          throw new IllegalBlockingModeException();
386    
387        impl.accept(socket.impl);
388        socket.bound = true;
389        socket.implCreated = true;
390    
391        SecurityManager sm = System.getSecurityManager();
392        if (sm != null)
393          sm.checkAccept(socket.getInetAddress().getHostAddress(),
394                         socket.getPort());
395      }
396    
397      /**
398       * Closes this socket and stops listening for connections
399       *
400       * @exception IOException If an error occurs
401       */
402      public void close() throws IOException
403      {
404        if (impl != null)
405          {
406            impl.close();
407            impl = null;
408          }
409      }
410    
411      /**
412       * Returns the unique <code>ServerSocketChannel</code> object
413       * associated with this socket, if any.
414       *
415       * <p>The socket only has a <code>ServerSocketChannel</code> if its created
416       * by <code>ServerSocketChannel.open()</code>.</p>
417       *
418       * @return the associated socket channel, null if none exists
419       *
420       * @since 1.4
421       */
422      public ServerSocketChannel getChannel()
423      {
424        return null;
425      }
426    
427      /**
428       * Returns true when the socket is bound, otherwise false
429       *
430       * @return true if socket is bound, false otherwise
431       *
432       * @since 1.4
433       */
434      public boolean isBound()
435      {
436        return local != null;
437      }
438    
439      /**
440       * Returns true if the socket is closed, otherwise false
441       *
442       * @return true if socket is closed, false otherwise
443       *
444       * @since 1.4
445       */
446      public boolean isClosed()
447      {
448        ServerSocketChannel channel = getChannel();
449        return impl == null || (channel != null && ! channel.isOpen());
450      }
451    
452      /**
453       * Sets the value of SO_TIMEOUT.  A value of 0 implies that SO_TIMEOUT is
454       * disabled (ie, operations never time out).  This is the number of
455       * milliseconds a socket operation can block before an
456       * InterruptedIOException is thrown.
457       *
458       * @param timeout The new SO_TIMEOUT value
459       *
460       * @exception SocketException If an error occurs
461       *
462       * @since 1.1
463       */
464      public void setSoTimeout(int timeout) throws SocketException
465      {
466        if (isClosed())
467          throw new SocketException("ServerSocket is closed");
468    
469        if (timeout < 0)
470          throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");
471    
472        impl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
473      }
474    
475      /**
476       * Retrieves the current value of the SO_TIMEOUT setting.  A value of 0
477       * implies that SO_TIMEOUT is disabled (ie, operations never time out).
478       * This is the number of milliseconds a socket operation can block before
479       * an InterruptedIOException is thrown.
480       *
481       * @return The value of SO_TIMEOUT
482       *
483       * @exception IOException If an error occurs
484       *
485       * @since 1.1
486       */
487      public int getSoTimeout() throws IOException
488      {
489        if (isClosed())
490          throw new SocketException("ServerSocket is closed");
491    
492        Object timeout = impl.getOption(SocketOptions.SO_TIMEOUT);
493    
494        if (! (timeout instanceof Integer))
495          throw new IOException("Internal Error");
496    
497        return ((Integer) timeout).intValue();
498      }
499    
500      /**
501       * Enables/Disables the SO_REUSEADDR option
502       *
503       * @param on true if SO_REUSEADDR should be enabled, false otherwise
504       *
505       * @exception SocketException If an error occurs
506       *
507       * @since 1.4
508       */
509      public void setReuseAddress(boolean on) throws SocketException
510      {
511        if (isClosed())
512          throw new SocketException("ServerSocket is closed");
513    
514        impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
515      }
516    
517      /**
518       * Checks if the SO_REUSEADDR option is enabled
519       *
520       * @return true if SO_REUSEADDR is set, false otherwise
521       *
522       * @exception SocketException If an error occurs
523       *
524       * @since 1.4
525       */
526      public boolean getReuseAddress() throws SocketException
527      {
528        if (isClosed())
529          throw new SocketException("ServerSocket is closed");
530    
531        Object reuseaddr = impl.getOption(SocketOptions.SO_REUSEADDR);
532    
533        if (! (reuseaddr instanceof Boolean))
534          throw new SocketException("Internal Error");
535    
536        return ((Boolean) reuseaddr).booleanValue();
537      }
538    
539      /**
540       * This method sets the value for the system level socket option
541       * SO_RCVBUF to the specified value.  Note that valid values for this
542       * option are specific to a given operating system.
543       *
544       * @param size The new receive buffer size.
545       *
546       * @exception SocketException If an error occurs or Socket is not connected
547       * @exception IllegalArgumentException If size is 0 or negative
548       *
549       * @since 1.4
550       */
551      public void setReceiveBufferSize(int size) throws SocketException
552      {
553        if (isClosed())
554          throw new SocketException("ServerSocket is closed");
555    
556        if (size <= 0)
557          throw new IllegalArgumentException("SO_RCVBUF value must be > 0");
558    
559        impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
560      }
561    
562      /**
563       * This method returns the value of the system level socket option
564       * SO_RCVBUF, which is used by the operating system to tune buffer
565       * sizes for data transfers.
566       *
567       * @return The receive buffer size.
568       *
569       * @exception SocketException If an error occurs or Socket is not connected
570       *
571       * @since 1.4
572       */
573      public int getReceiveBufferSize() throws SocketException
574      {
575        if (isClosed())
576          throw new SocketException("ServerSocket is closed");
577    
578        Object buf = impl.getOption(SocketOptions.SO_RCVBUF);
579    
580        if (! (buf instanceof Integer))
581          throw new SocketException("Internal Error: Unexpected type");
582    
583        return ((Integer) buf).intValue();
584      }
585    
586      /**
587       * Returns the value of this socket as a <code>String</code>.
588       *
589       * @return This socket represented as a <code>String</code>.
590       */
591      public String toString()
592      {
593        if (! isBound())
594          return "ServerSocket[unbound]";
595    
596        return ("ServerSocket[addr=" + getInetAddress() + ",port="
597               + port + ",localport=" + getLocalPort() + "]");
598      }
599    
600      /**
601       * Sets the <code>SocketImplFactory</code> for all
602       * <code>ServerSocket</code>'s.  This may only be done
603       * once per virtual machine.  Subsequent attempts will generate an
604       * exception.  Note that a <code>SecurityManager</code> check is made prior
605       * to setting the factory.  If insufficient privileges exist to set the
606       * factory, an exception will be thrown
607       *
608       * @param fac the factory to set
609       *
610       * @exception SecurityException If this operation is not allowed by the
611       * <code>SecurityManager</code>.
612       * @exception SocketException If the factory object is already defined
613       * @exception IOException If any other error occurs
614       */
615      public static synchronized void setSocketFactory(SocketImplFactory fac)
616        throws IOException
617      {
618        if (factory != null)
619          throw new SocketException("SocketFactory already defined");
620    
621        SecurityManager sm = System.getSecurityManager();
622        if (sm != null)
623          sm.checkSetFactory();
624    
625        factory = fac;
626      }
627    }