Save This Page
Home » openjdk-7 » java » net » [javadoc | source]
    1   /*
    2    * Copyright 1995-2007 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package java.net;
   27   
   28   import java.io.FileDescriptor;
   29   import java.io.IOException;
   30   import java.nio.channels.ServerSocketChannel;
   31   import java.security.AccessController;
   32   import java.security.PrivilegedExceptionAction;
   33   
   34   /**
   35    * This class implements server sockets. A server socket waits for
   36    * requests to come in over the network. It performs some operation
   37    * based on that request, and then possibly returns a result to the requester.
   38    * <p>
   39    * The actual work of the server socket is performed by an instance
   40    * of the <code>SocketImpl</code> class. An application can
   41    * change the socket factory that creates the socket
   42    * implementation to configure itself to create sockets
   43    * appropriate to the local firewall.
   44    *
   45    * @author  unascribed
   46    * @see     java.net.SocketImpl
   47    * @see     java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
   48    * @see     java.nio.channels.ServerSocketChannel
   49    * @since   JDK1.0
   50    */
   51   public
   52   class ServerSocket implements java.io.Closeable {
   53       /**
   54        * Various states of this socket.
   55        */
   56       private boolean created = false;
   57       private boolean bound = false;
   58       private boolean closed = false;
   59       private Object closeLock = new Object();
   60   
   61       /**
   62        * The implementation of this Socket.
   63        */
   64       private SocketImpl impl;
   65   
   66       /**
   67        * Are we using an older SocketImpl?
   68        */
   69       private boolean oldImpl = false;
   70   
   71       /**
   72        * Creates an unbound server socket.
   73        *
   74        * @exception IOException IO error when opening the socket.
   75        * @revised 1.4
   76        */
   77       public ServerSocket() throws IOException {
   78           setImpl();
   79       }
   80   
   81       /**
   82        * Creates a server socket, bound to the specified port. A port number
   83        * of <code>0</code> means that the port number is automatically
   84        * allocated, typically from an ephemeral port range. This port
   85        * number can then be retrieved by calling {@link #getLocalPort getLocalPort}.
   86        * <p>
   87        * The maximum queue length for incoming connection indications (a
   88        * request to connect) is set to <code>50</code>. If a connection
   89        * indication arrives when the queue is full, the connection is refused.
   90        * <p>
   91        * If the application has specified a server socket factory, that
   92        * factory's <code>createSocketImpl</code> method is called to create
   93        * the actual socket implementation. Otherwise a "plain" socket is created.
   94        * <p>
   95        * If there is a security manager,
   96        * its <code>checkListen</code> method is called
   97        * with the <code>port</code> argument
   98        * as its argument to ensure the operation is allowed.
   99        * This could result in a SecurityException.
  100        *
  101        *
  102        * @param      port  the port number, or <code>0</code> to use a port
  103        *                   number that is automatically allocated.
  104        *
  105        * @exception  IOException  if an I/O error occurs when opening the socket.
  106        * @exception  SecurityException
  107        * if a security manager exists and its <code>checkListen</code>
  108        * method doesn't allow the operation.
  109        * @exception  IllegalArgumentException if the port parameter is outside
  110        *             the specified range of valid port values, which is between
  111        *             0 and 65535, inclusive.
  112        *
  113        * @see        java.net.SocketImpl
  114        * @see        java.net.SocketImplFactory#createSocketImpl()
  115        * @see        java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  116        * @see        SecurityManager#checkListen
  117        */
  118       public ServerSocket(int port) throws IOException {
  119           this(port, 50, null);
  120       }
  121   
  122       /**
  123        * Creates a server socket and binds it to the specified local port
  124        * number, with the specified backlog.
  125        * A port number of <code>0</code> means that the port number is
  126        * automatically allocated, typically from an ephemeral port range.
  127        * This port number can then be retrieved by calling
  128        * {@link #getLocalPort getLocalPort}.
  129        * <p>
  130        * The maximum queue length for incoming connection indications (a
  131        * request to connect) is set to the <code>backlog</code> parameter. If
  132        * a connection indication arrives when the queue is full, the
  133        * connection is refused.
  134        * <p>
  135        * If the application has specified a server socket factory, that
  136        * factory's <code>createSocketImpl</code> method is called to create
  137        * the actual socket implementation. Otherwise a "plain" socket is created.
  138        * <p>
  139        * If there is a security manager,
  140        * its <code>checkListen</code> method is called
  141        * with the <code>port</code> argument
  142        * as its argument to ensure the operation is allowed.
  143        * This could result in a SecurityException.
  144        *
  145        * <P>The <code>backlog</code> argument must be a positive
  146        * value greater than 0. If the value passed is equal or less
  147        * than 0, then the default value will be assumed.
  148        * <P>
  149        *
  150        * @param      port     the port number, or <code>0</code> to use a port
  151        *                      number that is automatically allocated.
  152        * @param      backlog  the maximum length of the queue.
  153        *
  154        * @exception  IOException  if an I/O error occurs when opening the socket.
  155        * @exception  SecurityException
  156        * if a security manager exists and its <code>checkListen</code>
  157        * method doesn't allow the operation.
  158        * @exception  IllegalArgumentException if the port parameter is outside
  159        *             the specified range of valid port values, which is between
  160        *             0 and 65535, inclusive.
  161        *
  162        * @see        java.net.SocketImpl
  163        * @see        java.net.SocketImplFactory#createSocketImpl()
  164        * @see        java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
  165        * @see        SecurityManager#checkListen
  166        */
  167       public ServerSocket(int port, int backlog) throws IOException {
  168           this(port, backlog, null);
  169       }
  170   
  171       /**
  172        * Create a server with the specified port, listen backlog, and
  173        * local IP address to bind to.  The <i>bindAddr</i> argument
  174        * can be used on a multi-homed host for a ServerSocket that
  175        * will only accept connect requests to one of its addresses.
  176        * If <i>bindAddr</i> is null, it will default accepting
  177        * connections on any/all local addresses.
  178        * The port must be between 0 and 65535, inclusive.
  179        * A port number of <code>0</code> means that the port number is
  180        * automatically allocated, typically from an ephemeral port range.
  181        * This port number can then be retrieved by calling
  182        * {@link #getLocalPort getLocalPort}.
  183        *
  184        * <P>If there is a security manager, this method
  185        * calls its <code>checkListen</code> method
  186        * with the <code>port</code> argument
  187        * as its argument to ensure the operation is allowed.
  188        * This could result in a SecurityException.
  189        *
  190        * <P>The <code>backlog</code> argument must be a positive
  191        * value greater than 0. If the value passed is equal or less
  192        * than 0, then the default value will be assumed.
  193        * <P>
  194        * @param port  the port number, or <code>0</code> to use a port
  195        *              number that is automatically allocated.
  196        * @param backlog the listen backlog
  197        * @param bindAddr the local InetAddress the server will bind to
  198        *
  199        * @throws  SecurityException if a security manager exists and
  200        * its <code>checkListen</code> method doesn't allow the operation.
  201        *
  202        * @throws  IOException if an I/O error occurs when opening the socket.
  203        * @exception  IllegalArgumentException if the port parameter is outside
  204        *             the specified range of valid port values, which is between
  205        *             0 and 65535, inclusive.
  206        *
  207        * @see SocketOptions
  208        * @see SocketImpl
  209        * @see SecurityManager#checkListen
  210        * @since   JDK1.1
  211        */
  212       public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {
  213           setImpl();
  214           if (port < 0 || port > 0xFFFF)
  215               throw new IllegalArgumentException(
  216                          "Port value out of range: " + port);
  217           if (backlog < 1)
  218             backlog = 50;
  219           try {
  220               bind(new InetSocketAddress(bindAddr, port), backlog);
  221           } catch(SecurityException e) {
  222               close();
  223               throw e;
  224           } catch(IOException e) {
  225               close();
  226               throw e;
  227           }
  228       }
  229   
  230       /**
  231        * Get the <code>SocketImpl</code> attached to this socket, creating
  232        * it if necessary.
  233        *
  234        * @return  the <code>SocketImpl</code> attached to that ServerSocket.
  235        * @throws SocketException if creation fails.
  236        * @since 1.4
  237        */
  238       SocketImpl getImpl() throws SocketException {
  239           if (!created)
  240               createImpl();
  241           return impl;
  242       }
  243   
  244       private void checkOldImpl() {
  245           if (impl == null)
  246               return;
  247           // SocketImpl.connect() is a protected method, therefore we need to use
  248           // getDeclaredMethod, therefore we need permission to access the member
  249           try {
  250               AccessController.doPrivileged(
  251                   new PrivilegedExceptionAction<Void>() {
  252                       public Void run() throws NoSuchMethodException {
  253                           Class[] cl = new Class[2];
  254                           cl[0] = SocketAddress.class;
  255                           cl[1] = Integer.TYPE;
  256                           impl.getClass().getDeclaredMethod("connect", cl);
  257                           return null;
  258                       }
  259                   });
  260           } catch (java.security.PrivilegedActionException e) {
  261               oldImpl = true;
  262           }
  263       }
  264   
  265       private void setImpl() {
  266           if (factory != null) {
  267               impl = factory.createSocketImpl();
  268               checkOldImpl();
  269           } else {
  270               // No need to do a checkOldImpl() here, we know it's an up to date
  271               // SocketImpl!
  272               impl = new SocksSocketImpl();
  273           }
  274           if (impl != null)
  275               impl.setServerSocket(this);
  276       }
  277   
  278       /**
  279        * Creates the socket implementation.
  280        *
  281        * @throws IOException if creation fails
  282        * @since 1.4
  283        */
  284       void createImpl() throws SocketException {
  285           if (impl == null)
  286               setImpl();
  287           try {
  288               impl.create(true);
  289               created = true;
  290           } catch (IOException e) {
  291               throw new SocketException(e.getMessage());
  292           }
  293       }
  294   
  295       /**
  296        *
  297        * Binds the <code>ServerSocket</code> to a specific address
  298        * (IP address and port number).
  299        * <p>
  300        * If the address is <code>null</code>, then the system will pick up
  301        * an ephemeral port and a valid local address to bind the socket.
  302        * <p>
  303        * @param   endpoint        The IP address & port number to bind to.
  304        * @throws  IOException if the bind operation fails, or if the socket
  305        *                     is already bound.
  306        * @throws  SecurityException       if a <code>SecurityManager</code> is present and
  307        * its <code>checkListen</code> method doesn't allow the operation.
  308        * @throws  IllegalArgumentException if endpoint is a
  309        *          SocketAddress subclass not supported by this socket
  310        * @since 1.4
  311        */
  312       public void bind(SocketAddress endpoint) throws IOException {
  313           bind(endpoint, 50);
  314       }
  315   
  316       /**
  317        *
  318        * Binds the <code>ServerSocket</code> to a specific address
  319        * (IP address and port number).
  320        * <p>
  321        * If the address is <code>null</code>, then the system will pick up
  322        * an ephemeral port and a valid local address to bind the socket.
  323        * <P>
  324        * The <code>backlog</code> argument must be a positive
  325        * value greater than 0. If the value passed is equal or less
  326        * than 0, then the default value will be assumed.
  327        * @param   endpoint        The IP address & port number to bind to.
  328        * @param   backlog         The listen backlog length.
  329        * @throws  IOException if the bind operation fails, or if the socket
  330        *                     is already bound.
  331        * @throws  SecurityException       if a <code>SecurityManager</code> is present and
  332        * its <code>checkListen</code> method doesn't allow the operation.
  333        * @throws  IllegalArgumentException if endpoint is a
  334        *          SocketAddress subclass not supported by this socket
  335        * @since 1.4
  336        */
  337       public void bind(SocketAddress endpoint, int backlog) throws IOException {
  338           if (isClosed())
  339               throw new SocketException("Socket is closed");
  340           if (!oldImpl && isBound())
  341               throw new SocketException("Already bound");
  342           if (endpoint == null)
  343               endpoint = new InetSocketAddress(0);
  344           if (!(endpoint instanceof InetSocketAddress))
  345               throw new IllegalArgumentException("Unsupported address type");
  346           InetSocketAddress epoint = (InetSocketAddress) endpoint;
  347           if (epoint.isUnresolved())
  348               throw new SocketException("Unresolved address");
  349           if (backlog < 1)
  350             backlog = 50;
  351           try {
  352               SecurityManager security = System.getSecurityManager();
  353               if (security != null)
  354                   security.checkListen(epoint.getPort());
  355               getImpl().bind(epoint.getAddress(), epoint.getPort());
  356               getImpl().listen(backlog);
  357               bound = true;
  358           } catch(SecurityException e) {
  359               bound = false;
  360               throw e;
  361           } catch(IOException e) {
  362               bound = false;
  363               throw e;
  364           }
  365       }
  366   
  367       /**
  368        * Returns the local address of this server socket.
  369        * <p>
  370        * If the socket was bound prior to being {@link #close closed},
  371        * then this method will continue to return the local address
  372        * after the socket is closed.
  373        *
  374        * @return  the address to which this socket is bound,
  375        *          or <code>null</code> if the socket is unbound.
  376        */
  377       public InetAddress getInetAddress() {
  378           if (!isBound())
  379               return null;
  380           try {
  381               return getImpl().getInetAddress();
  382           } catch (SocketException e) {
  383               // nothing
  384               // If we're bound, the impl has been created
  385               // so we shouldn't get here
  386           }
  387           return null;
  388       }
  389   
  390       /**
  391        * Returns the port number on which this socket is listening.
  392        * <p>
  393        * If the socket was bound prior to being {@link #close closed},
  394        * then this method will continue to return the port number
  395        * after the socket is closed.
  396        *
  397        * @return  the port number to which this socket is listening or
  398        *          -1 if the socket is not bound yet.
  399        */
  400       public int getLocalPort() {
  401           if (!isBound())
  402               return -1;
  403           try {
  404               return getImpl().getLocalPort();
  405           } catch (SocketException e) {
  406               // nothing
  407               // If we're bound, the impl has been created
  408               // so we shouldn't get here
  409           }
  410           return -1;
  411       }
  412   
  413       /**
  414        * Returns the address of the endpoint this socket is bound to, or
  415        * <code>null</code> if it is not bound yet.
  416        * <p>
  417        * If the socket was bound prior to being {@link #close closed},
  418        * then this method will continue to return the address of the endpoint
  419        * after the socket is closed.
  420        *
  421        * @return a <code>SocketAddress</code> representing the local endpoint of this
  422        *         socket, or <code>null</code> if it is not bound yet.
  423        * @see #getInetAddress()
  424        * @see #getLocalPort()
  425        * @see #bind(SocketAddress)
  426        * @since 1.4
  427        */
  428   
  429       public SocketAddress getLocalSocketAddress() {
  430           if (!isBound())
  431               return null;
  432           return new InetSocketAddress(getInetAddress(), getLocalPort());
  433       }
  434   
  435       /**
  436        * Listens for a connection to be made to this socket and accepts
  437        * it. The method blocks until a connection is made.
  438        *
  439        * <p>A new Socket <code>s</code> is created and, if there
  440        * is a security manager,
  441        * the security manager's <code>checkAccept</code> method is called
  442        * with <code>s.getInetAddress().getHostAddress()</code> and
  443        * <code>s.getPort()</code>
  444        * as its arguments to ensure the operation is allowed.
  445        * This could result in a SecurityException.
  446        *
  447        * @exception  IOException  if an I/O error occurs when waiting for a
  448        *               connection.
  449        * @exception  SecurityException  if a security manager exists and its
  450        *             <code>checkAccept</code> method doesn't allow the operation.
  451        * @exception  SocketTimeoutException if a timeout was previously set with setSoTimeout and
  452        *             the timeout has been reached.
  453        * @exception  java.nio.channels.IllegalBlockingModeException
  454        *             if this socket has an associated channel, the channel is in
  455        *             non-blocking mode, and there is no connection ready to be
  456        *             accepted
  457        *
  458        * @return the new Socket
  459        * @see SecurityManager#checkAccept
  460        * @revised 1.4
  461        * @spec JSR-51
  462        */
  463       public Socket accept() throws IOException {
  464           if (isClosed())
  465               throw new SocketException("Socket is closed");
  466           if (!isBound())
  467               throw new SocketException("Socket is not bound yet");
  468           Socket s = new Socket((SocketImpl) null);
  469           implAccept(s);
  470           return s;
  471       }
  472   
  473       /**
  474        * Subclasses of ServerSocket use this method to override accept()
  475        * to return their own subclass of socket.  So a FooServerSocket
  476        * will typically hand this method an <i>empty</i> FooSocket.  On
  477        * return from implAccept the FooSocket will be connected to a client.
  478        *
  479        * @param s the Socket
  480        * @throws java.nio.channels.IllegalBlockingModeException
  481        *         if this socket has an associated channel,
  482        *         and the channel is in non-blocking mode
  483        * @throws IOException if an I/O error occurs when waiting
  484        * for a connection.
  485        * @since   JDK1.1
  486        * @revised 1.4
  487        * @spec JSR-51
  488        */
  489       protected final void implAccept(Socket s) throws IOException {
  490           SocketImpl si = null;
  491           try {
  492               if (s.impl == null)
  493                 s.setImpl();
  494               else {
  495                   s.impl.reset();
  496               }
  497               si = s.impl;
  498               s.impl = null;
  499               si.address = new InetAddress();
  500               si.fd = new FileDescriptor();
  501               getImpl().accept(si);
  502   
  503               SecurityManager security = System.getSecurityManager();
  504               if (security != null) {
  505                   security.checkAccept(si.getInetAddress().getHostAddress(),
  506                                        si.getPort());
  507               }
  508           } catch (IOException e) {
  509               if (si != null)
  510                   si.reset();
  511               s.impl = si;
  512               throw e;
  513           } catch (SecurityException e) {
  514               if (si != null)
  515                   si.reset();
  516               s.impl = si;
  517               throw e;
  518           }
  519           s.impl = si;
  520           s.postAccept();
  521       }
  522   
  523       /**
  524        * Closes this socket.
  525        *
  526        * Any thread currently blocked in {@link #accept()} will throw
  527        * a {@link SocketException}.
  528        *
  529        * <p> If this socket has an associated channel then the channel is closed
  530        * as well.
  531        *
  532        * @exception  IOException  if an I/O error occurs when closing the socket.
  533        * @revised 1.4
  534        * @spec JSR-51
  535        */
  536       public void close() throws IOException {
  537           synchronized(closeLock) {
  538               if (isClosed())
  539                   return;
  540               if (created)
  541                   impl.close();
  542               closed = true;
  543           }
  544       }
  545   
  546       /**
  547        * Returns the unique {@link java.nio.channels.ServerSocketChannel} object
  548        * associated with this socket, if any.
  549        *
  550        * <p> A server socket will have a channel if, and only if, the channel
  551        * itself was created via the {@link
  552        * java.nio.channels.ServerSocketChannel#open ServerSocketChannel.open}
  553        * method.
  554        *
  555        * @return  the server-socket channel associated with this socket,
  556        *          or <tt>null</tt> if this socket was not created
  557        *          for a channel
  558        *
  559        * @since 1.4
  560        * @spec JSR-51
  561        */
  562       public ServerSocketChannel getChannel() {
  563           return null;
  564       }
  565   
  566       /**
  567        * Returns the binding state of the ServerSocket.
  568        *
  569        * @return true if the ServerSocket succesfuly bound to an address
  570        * @since 1.4
  571        */
  572       public boolean isBound() {
  573           // Before 1.3 ServerSockets were always bound during creation
  574           return bound || oldImpl;
  575       }
  576   
  577       /**
  578        * Returns the closed state of the ServerSocket.
  579        *
  580        * @return true if the socket has been closed
  581        * @since 1.4
  582        */
  583       public boolean isClosed() {
  584           synchronized(closeLock) {
  585               return closed;
  586           }
  587       }
  588   
  589       /**
  590        * Enable/disable SO_TIMEOUT with the specified timeout, in
  591        * milliseconds.  With this option set to a non-zero timeout,
  592        * a call to accept() for this ServerSocket
  593        * will block for only this amount of time.  If the timeout expires,
  594        * a <B>java.net.SocketTimeoutException</B> is raised, though the
  595        * ServerSocket is still valid.  The option <B>must</B> be enabled
  596        * prior to entering the blocking operation to have effect.  The
  597        * timeout must be > 0.
  598        * A timeout of zero is interpreted as an infinite timeout.
  599        * @param timeout the specified timeout, in milliseconds
  600        * @exception SocketException if there is an error in
  601        * the underlying protocol, such as a TCP error.
  602        * @since   JDK1.1
  603        * @see #getSoTimeout()
  604        */
  605       public synchronized void setSoTimeout(int timeout) throws SocketException {
  606           if (isClosed())
  607               throw new SocketException("Socket is closed");
  608           getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
  609       }
  610   
  611       /**
  612        * Retrieve setting for SO_TIMEOUT.  0 returns implies that the
  613        * option is disabled (i.e., timeout of infinity).
  614        * @return the SO_TIMEOUT value
  615        * @exception IOException if an I/O error occurs
  616        * @since   JDK1.1
  617        * @see #setSoTimeout(int)
  618        */
  619       public synchronized int getSoTimeout() throws IOException {
  620           if (isClosed())
  621               throw new SocketException("Socket is closed");
  622           Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
  623           /* extra type safety */
  624           if (o instanceof Integer) {
  625               return ((Integer) o).intValue();
  626           } else {
  627               return 0;
  628           }
  629       }
  630   
  631       /**
  632        * Enable/disable the SO_REUSEADDR socket option.
  633        * <p>
  634        * When a TCP connection is closed the connection may remain
  635        * in a timeout state for a period of time after the connection
  636        * is closed (typically known as the <tt>TIME_WAIT</tt> state
  637        * or <tt>2MSL</tt> wait state).
  638        * For applications using a well known socket address or port
  639        * it may not be possible to bind a socket to the required
  640        * <tt>SocketAddress</tt> if there is a connection in the
  641        * timeout state involving the socket address or port.
  642        * <p>
  643        * Enabling <tt>SO_REUSEADDR</tt> prior to binding the socket
  644        * using {@link #bind(SocketAddress)} allows the socket to be
  645        * bound even though a previous connection is in a timeout
  646        * state.
  647        * <p>
  648        * When a <tt>ServerSocket</tt> is created the initial setting
  649        * of <tt>SO_REUSEADDR</tt> is not defined. Applications can
  650        * use {@link #getReuseAddress()} to determine the initial
  651        * setting of <tt>SO_REUSEADDR</tt>.
  652        * <p>
  653        * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
  654        * disabled after a socket is bound (See {@link #isBound()})
  655        * is not defined.
  656        *
  657        * @param on  whether to enable or disable the socket option
  658        * @exception SocketException if an error occurs enabling or
  659        *            disabling the <tt>SO_RESUEADDR</tt> socket option,
  660        *            or the socket is closed.
  661        * @since 1.4
  662        * @see #getReuseAddress()
  663        * @see #bind(SocketAddress)
  664        * @see #isBound()
  665        * @see #isClosed()
  666        */
  667       public void setReuseAddress(boolean on) throws SocketException {
  668           if (isClosed())
  669               throw new SocketException("Socket is closed");
  670           getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
  671       }
  672   
  673       /**
  674        * Tests if SO_REUSEADDR is enabled.
  675        *
  676        * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
  677        * @exception SocketException if there is an error
  678        * in the underlying protocol, such as a TCP error.
  679        * @since   1.4
  680        * @see #setReuseAddress(boolean)
  681        */
  682       public boolean getReuseAddress() throws SocketException {
  683           if (isClosed())
  684               throw new SocketException("Socket is closed");
  685           return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
  686       }
  687   
  688       /**
  689        * Returns the implementation address and implementation port of
  690        * this socket as a <code>String</code>.
  691        *
  692        * @return  a string representation of this socket.
  693        */
  694       public String toString() {
  695           if (!isBound())
  696               return "ServerSocket[unbound]";
  697           return "ServerSocket[addr=" + impl.getInetAddress() +
  698                   ",port=" + impl.getPort() +
  699                   ",localport=" + impl.getLocalPort()  + "]";
  700       }
  701   
  702       void setBound() {
  703           bound = true;
  704       }
  705   
  706       void setCreated() {
  707           created = true;
  708       }
  709   
  710       /**
  711        * The factory for all server sockets.
  712        */
  713       private static SocketImplFactory factory = null;
  714   
  715       /**
  716        * Sets the server socket implementation factory for the
  717        * application. The factory can be specified only once.
  718        * <p>
  719        * When an application creates a new server socket, the socket
  720        * implementation factory's <code>createSocketImpl</code> method is
  721        * called to create the actual socket implementation.
  722        * <p>
  723        * Passing <code>null</code> to the method is a no-op unless the factory
  724        * was already set.
  725        * <p>
  726        * If there is a security manager, this method first calls
  727        * the security manager's <code>checkSetFactory</code> method
  728        * to ensure the operation is allowed.
  729        * This could result in a SecurityException.
  730        *
  731        * @param      fac   the desired factory.
  732        * @exception  IOException  if an I/O error occurs when setting the
  733        *               socket factory.
  734        * @exception  SocketException  if the factory has already been defined.
  735        * @exception  SecurityException  if a security manager exists and its
  736        *             <code>checkSetFactory</code> method doesn't allow the operation.
  737        * @see        java.net.SocketImplFactory#createSocketImpl()
  738        * @see        SecurityManager#checkSetFactory
  739        */
  740       public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException {
  741           if (factory != null) {
  742               throw new SocketException("factory already defined");
  743           }
  744           SecurityManager security = System.getSecurityManager();
  745           if (security != null) {
  746               security.checkSetFactory();
  747           }
  748           factory = fac;
  749       }
  750   
  751       /**
  752        * Sets a default proposed value for the SO_RCVBUF option for sockets
  753        * accepted from this <tt>ServerSocket</tt>. The value actually set
  754        * in the accepted socket must be determined by calling
  755        * {@link Socket#getReceiveBufferSize()} after the socket
  756        * is returned by {@link #accept()}.
  757        * <p>
  758        * The value of SO_RCVBUF is used both to set the size of the internal
  759        * socket receive buffer, and to set the size of the TCP receive window
  760        * that is advertized to the remote peer.
  761        * <p>
  762        * It is possible to change the value subsequently, by calling
  763        * {@link Socket#setReceiveBufferSize(int)}. However, if the application
  764        * wishes to allow a receive window larger than 64K bytes, as defined by RFC1323
  765        * then the proposed value must be set in the ServerSocket <B>before</B>
  766        * it is bound to a local address. This implies, that the ServerSocket must be
  767        * created with the no-argument constructor, then setReceiveBufferSize() must
  768        * be called and lastly the ServerSocket is bound to an address by calling bind().
  769        * <p>
  770        * Failure to do this will not cause an error, and the buffer size may be set to the
  771        * requested value but the TCP receive window in sockets accepted from
  772        * this ServerSocket will be no larger than 64K bytes.
  773        *
  774        * @exception SocketException if there is an error
  775        * in the underlying protocol, such as a TCP error.
  776        *
  777        * @param size the size to which to set the receive buffer
  778        * size. This value must be greater than 0.
  779        *
  780        * @exception IllegalArgumentException if the
  781        * value is 0 or is negative.
  782        *
  783        * @since 1.4
  784        * @see #getReceiveBufferSize
  785        */
  786        public synchronized void setReceiveBufferSize (int size) throws SocketException {
  787           if (!(size > 0)) {
  788               throw new IllegalArgumentException("negative receive size");
  789           }
  790           if (isClosed())
  791               throw new SocketException("Socket is closed");
  792           getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
  793       }
  794   
  795       /**
  796        * Gets the value of the SO_RCVBUF option for this <tt>ServerSocket</tt>,
  797        * that is the proposed buffer size that will be used for Sockets accepted
  798        * from this <tt>ServerSocket</tt>.
  799        *
  800        * <p>Note, the value actually set in the accepted socket is determined by
  801        * calling {@link Socket#getReceiveBufferSize()}.
  802        * @return the value of the SO_RCVBUF option for this <tt>Socket</tt>.
  803        * @exception SocketException if there is an error
  804        * in the underlying protocol, such as a TCP error.
  805        * @see #setReceiveBufferSize(int)
  806        * @since 1.4
  807        */
  808       public synchronized int getReceiveBufferSize()
  809       throws SocketException{
  810           if (isClosed())
  811               throw new SocketException("Socket is closed");
  812           int result = 0;
  813           Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
  814           if (o instanceof Integer) {
  815               result = ((Integer)o).intValue();
  816           }
  817           return result;
  818       }
  819   
  820       /**
  821        * Sets performance preferences for this ServerSocket.
  822        *
  823        * <p> Sockets use the TCP/IP protocol by default.  Some implementations
  824        * may offer alternative protocols which have different performance
  825        * characteristics than TCP/IP.  This method allows the application to
  826        * express its own preferences as to how these tradeoffs should be made
  827        * when the implementation chooses from the available protocols.
  828        *
  829        * <p> Performance preferences are described by three integers
  830        * whose values indicate the relative importance of short connection time,
  831        * low latency, and high bandwidth.  The absolute values of the integers
  832        * are irrelevant; in order to choose a protocol the values are simply
  833        * compared, with larger values indicating stronger preferences.  If the
  834        * application prefers short connection time over both low latency and high
  835        * bandwidth, for example, then it could invoke this method with the values
  836        * <tt>(1, 0, 0)</tt>.  If the application prefers high bandwidth above low
  837        * latency, and low latency above short connection time, then it could
  838        * invoke this method with the values <tt>(0, 1, 2)</tt>.
  839        *
  840        * <p> Invoking this method after this socket has been bound
  841        * will have no effect. This implies that in order to use this capability
  842        * requires the socket to be created with the no-argument constructor.
  843        *
  844        * @param  connectionTime
  845        *         An <tt>int</tt> expressing the relative importance of a short
  846        *         connection time
  847        *
  848        * @param  latency
  849        *         An <tt>int</tt> expressing the relative importance of low
  850        *         latency
  851        *
  852        * @param  bandwidth
  853        *         An <tt>int</tt> expressing the relative importance of high
  854        *         bandwidth
  855        *
  856        * @since 1.5
  857        */
  858       public void setPerformancePreferences(int connectionTime,
  859                                             int latency,
  860                                             int bandwidth)
  861       {
  862           /* Not implemented yet */
  863       }
  864   
  865   }

Save This Page
Home » openjdk-7 » java » net » [javadoc | source]