Save This Page
Home » openjdk-7 » java » net » [javadoc | source]
    1   /*
    2    * Copyright 1995-2008 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.InputStream;
   29   import java.io.OutputStream;
   30   import java.io.IOException;
   31   import java.io.InterruptedIOException;
   32   import java.nio.channels.SocketChannel;
   33   import java.security.AccessController;
   34   import java.security.PrivilegedExceptionAction;
   35   import java.security.PrivilegedAction;
   36   
   37   /**
   38    * This class implements client sockets (also called just
   39    * "sockets"). A socket is an endpoint for communication
   40    * between two machines.
   41    * <p>
   42    * The actual work of the socket is performed by an instance of the
   43    * <code>SocketImpl</code> class. An application, by changing
   44    * the socket factory that creates the socket implementation,
   45    * can configure itself to create sockets appropriate to the local
   46    * firewall.
   47    *
   48    * @author  unascribed
   49    * @see     java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
   50    * @see     java.net.SocketImpl
   51    * @see     java.nio.channels.SocketChannel
   52    * @since   JDK1.0
   53    */
   54   public
   55   class Socket implements java.io.Closeable {
   56       /**
   57        * Various states of this socket.
   58        */
   59       private boolean created = false;
   60       private boolean bound = false;
   61       private boolean connected = false;
   62       private boolean closed = false;
   63       private Object closeLock = new Object();
   64       private boolean shutIn = false;
   65       private boolean shutOut = false;
   66   
   67       /**
   68        * The implementation of this Socket.
   69        */
   70       SocketImpl impl;
   71   
   72       /**
   73        * Are we using an older SocketImpl?
   74        */
   75       private boolean oldImpl = false;
   76   
   77       /**
   78        * Creates an unconnected socket, with the
   79        * system-default type of SocketImpl.
   80        *
   81        * @since   JDK1.1
   82        * @revised 1.4
   83        */
   84       public Socket() {
   85           setImpl();
   86       }
   87   
   88       /**
   89        * Creates an unconnected socket, specifying the type of proxy, if any,
   90        * that should be used regardless of any other settings.
   91        * <P>
   92        * If there is a security manager, its <code>checkConnect</code> method
   93        * is called with the proxy host address and port number
   94        * as its arguments. This could result in a SecurityException.
   95        * <P>
   96        * Examples:
   97        * <UL> <LI><code>Socket s = new Socket(Proxy.NO_PROXY);</code> will create
   98        * a plain socket ignoring any other proxy configuration.</LI>
   99        * <LI><code>Socket s = new Socket(new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("socks.mydom.com", 1080)));</code>
  100        * will create a socket connecting through the specified SOCKS proxy
  101        * server.</LI>
  102        * </UL>
  103        *
  104        * @param proxy a {@link java.net.Proxy Proxy} object specifying what kind
  105        *              of proxying should be used.
  106        * @throws IllegalArgumentException if the proxy is of an invalid type
  107        *          or <code>null</code>.
  108        * @throws SecurityException if a security manager is present and
  109        *                           permission to connect to the proxy is
  110        *                           denied.
  111        * @see java.net.ProxySelector
  112        * @see java.net.Proxy
  113        *
  114        * @since   1.5
  115        */
  116       public Socket(Proxy proxy) {
  117           if (proxy != null && proxy.type() == Proxy.Type.SOCKS) {
  118               SecurityManager security = System.getSecurityManager();
  119               InetSocketAddress epoint = (InetSocketAddress) proxy.address();
  120               if (security != null) {
  121                   if (epoint.isUnresolved())
  122                       security.checkConnect(epoint.getHostName(),
  123                                             epoint.getPort());
  124                   else
  125                       security.checkConnect(epoint.getAddress().getHostAddress(),
  126                                             epoint.getPort());
  127               }
  128               impl = new SocksSocketImpl(proxy);
  129               impl.setSocket(this);
  130           } else {
  131               if (proxy == Proxy.NO_PROXY) {
  132                   if (factory == null) {
  133                       impl = new PlainSocketImpl();
  134                       impl.setSocket(this);
  135                   } else
  136                       setImpl();
  137               } else
  138                   throw new IllegalArgumentException("Invalid Proxy");
  139           }
  140       }
  141   
  142       /**
  143        * Creates an unconnected Socket with a user-specified
  144        * SocketImpl.
  145        * <P>
  146        * @param impl an instance of a <B>SocketImpl</B>
  147        * the subclass wishes to use on the Socket.
  148        *
  149        * @exception SocketException if there is an error in the underlying protocol,
  150        * such as a TCP error.
  151        * @since   JDK1.1
  152        */
  153       protected Socket(SocketImpl impl) throws SocketException {
  154           this.impl = impl;
  155           if (impl != null) {
  156               checkOldImpl();
  157               this.impl.setSocket(this);
  158           }
  159       }
  160   
  161       /**
  162        * Creates a stream socket and connects it to the specified port
  163        * number on the named host.
  164        * <p>
  165        * If the specified host is <tt>null</tt> it is the equivalent of
  166        * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
  167        * In other words, it is equivalent to specifying an address of the
  168        * loopback interface. </p>
  169        * <p>
  170        * If the application has specified a server socket factory, that
  171        * factory's <code>createSocketImpl</code> method is called to create
  172        * the actual socket implementation. Otherwise a "plain" socket is created.
  173        * <p>
  174        * If there is a security manager, its
  175        * <code>checkConnect</code> method is called
  176        * with the host address and <code>port</code>
  177        * as its arguments. This could result in a SecurityException.
  178        *
  179        * @param      host   the host name, or <code>null</code> for the loopback address.
  180        * @param      port   the port number.
  181        *
  182        * @exception  UnknownHostException if the IP address of
  183        * the host could not be determined.
  184        *
  185        * @exception  IOException  if an I/O error occurs when creating the socket.
  186        * @exception  SecurityException  if a security manager exists and its
  187        *             <code>checkConnect</code> method doesn't allow the operation.
  188        * @exception  IllegalArgumentException if the port parameter is outside
  189        *             the specified range of valid port values, which is between
  190        *             0 and 65535, inclusive.
  191        * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  192        * @see        java.net.SocketImpl
  193        * @see        java.net.SocketImplFactory#createSocketImpl()
  194        * @see        SecurityManager#checkConnect
  195        */
  196       public Socket(String host, int port)
  197           throws UnknownHostException, IOException
  198       {
  199           this(host != null ? new InetSocketAddress(host, port) :
  200                new InetSocketAddress(InetAddress.getByName(null), port),
  201                (SocketAddress) null, true);
  202       }
  203   
  204       /**
  205        * Creates a stream socket and connects it to the specified port
  206        * number at the specified IP address.
  207        * <p>
  208        * If the application has specified a socket factory, that factory's
  209        * <code>createSocketImpl</code> method is called to create the
  210        * actual socket implementation. Otherwise a "plain" socket is created.
  211        * <p>
  212        * If there is a security manager, its
  213        * <code>checkConnect</code> method is called
  214        * with the host address and <code>port</code>
  215        * as its arguments. This could result in a SecurityException.
  216        *
  217        * @param      address   the IP address.
  218        * @param      port      the port number.
  219        * @exception  IOException  if an I/O error occurs when creating the socket.
  220        * @exception  SecurityException  if a security manager exists and its
  221        *             <code>checkConnect</code> method doesn't allow the operation.
  222        * @exception  IllegalArgumentException if the port parameter is outside
  223        *             the specified range of valid port values, which is between
  224        *             0 and 65535, inclusive.
  225        * @exception  NullPointerException if <code>address</code> is null.
  226        * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  227        * @see        java.net.SocketImpl
  228        * @see        java.net.SocketImplFactory#createSocketImpl()
  229        * @see        SecurityManager#checkConnect
  230        */
  231       public Socket(InetAddress address, int port) throws IOException {
  232           this(address != null ? new InetSocketAddress(address, port) : null,
  233                (SocketAddress) null, true);
  234       }
  235   
  236       /**
  237        * Creates a socket and connects it to the specified remote host on
  238        * the specified remote port. The Socket will also bind() to the local
  239        * address and port supplied.
  240        * <p>
  241        * If the specified host is <tt>null</tt> it is the equivalent of
  242        * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
  243        * In other words, it is equivalent to specifying an address of the
  244        * loopback interface. </p>
  245        * <p>
  246        * A local port number of <code>zero</code> will let the system pick up a
  247        * free port in the <code>bind</code> operation.</p>
  248        * <p>
  249        * If there is a security manager, its
  250        * <code>checkConnect</code> method is called
  251        * with the host address and <code>port</code>
  252        * as its arguments. This could result in a SecurityException.
  253        *
  254        * @param host the name of the remote host, or <code>null</code> for the loopback address.
  255        * @param port the remote port
  256        * @param localAddr the local address the socket is bound to, or
  257        *        <code>null</code> for the <code>anyLocal</code> address.
  258        * @param localPort the local port the socket is bound to, or
  259        *        <code>zero</code> for a system selected free port.
  260        * @exception  IOException  if an I/O error occurs when creating the socket.
  261        * @exception  SecurityException  if a security manager exists and its
  262        *             <code>checkConnect</code> method doesn't allow the operation.
  263        * @exception  IllegalArgumentException if the port parameter or localPort
  264        *             parameter is outside the specified range of valid port values,
  265        *             which is between 0 and 65535, inclusive.
  266        * @see        SecurityManager#checkConnect
  267        * @since   JDK1.1
  268        */
  269       public Socket(String host, int port, InetAddress localAddr,
  270                     int localPort) throws IOException {
  271           this(host != null ? new InetSocketAddress(host, port) :
  272                  new InetSocketAddress(InetAddress.getByName(null), port),
  273                new InetSocketAddress(localAddr, localPort), true);
  274       }
  275   
  276       /**
  277        * Creates a socket and connects it to the specified remote address on
  278        * the specified remote port. The Socket will also bind() to the local
  279        * address and port supplied.
  280        * <p>
  281        * If the specified local address is <tt>null</tt> it is the equivalent of
  282        * specifying the address as the AnyLocal address (see <tt>{@link java.net.InetAddress#isAnyLocalAddress InetAddress.isAnyLocalAddress}()</tt>).
  283        * <p>
  284        * A local port number of <code>zero</code> will let the system pick up a
  285        * free port in the <code>bind</code> operation.</p>
  286        * <p>
  287        * If there is a security manager, its
  288        * <code>checkConnect</code> method is called
  289        * with the host address and <code>port</code>
  290        * as its arguments. This could result in a SecurityException.
  291        *
  292        * @param address the remote address
  293        * @param port the remote port
  294        * @param localAddr the local address the socket is bound to, or
  295        *        <code>null</code> for the <code>anyLocal</code> address.
  296        * @param localPort the local port the socket is bound to or
  297        *        <code>zero</code> for a system selected free port.
  298        * @exception  IOException  if an I/O error occurs when creating the socket.
  299        * @exception  SecurityException  if a security manager exists and its
  300        *             <code>checkConnect</code> method doesn't allow the operation.
  301        * @exception  IllegalArgumentException if the port parameter or localPort
  302        *             parameter is outside the specified range of valid port values,
  303        *             which is between 0 and 65535, inclusive.
  304        * @exception  NullPointerException if <code>address</code> is null.
  305        * @see        SecurityManager#checkConnect
  306        * @since   JDK1.1
  307        */
  308       public Socket(InetAddress address, int port, InetAddress localAddr,
  309                     int localPort) throws IOException {
  310           this(address != null ? new InetSocketAddress(address, port) : null,
  311                new InetSocketAddress(localAddr, localPort), true);
  312       }
  313   
  314       /**
  315        * Creates a stream socket and connects it to the specified port
  316        * number on the named host.
  317        * <p>
  318        * If the specified host is <tt>null</tt> it is the equivalent of
  319        * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
  320        * In other words, it is equivalent to specifying an address of the
  321        * loopback interface. </p>
  322        * <p>
  323        * If the stream argument is <code>true</code>, this creates a
  324        * stream socket. If the stream argument is <code>false</code>, it
  325        * creates a datagram socket.
  326        * <p>
  327        * If the application has specified a server socket factory, that
  328        * factory's <code>createSocketImpl</code> method is called to create
  329        * the actual socket implementation. Otherwise a "plain" socket is created.
  330        * <p>
  331        * If there is a security manager, its
  332        * <code>checkConnect</code> method is called
  333        * with the host address and <code>port</code>
  334        * as its arguments. This could result in a SecurityException.
  335        * <p>
  336        * If a UDP socket is used, TCP/IP related socket options will not apply.
  337        *
  338        * @param      host     the host name, or <code>null</code> for the loopback address.
  339        * @param      port     the port number.
  340        * @param      stream   a <code>boolean</code> indicating whether this is
  341        *                      a stream socket or a datagram socket.
  342        * @exception  IOException  if an I/O error occurs when creating the socket.
  343        * @exception  SecurityException  if a security manager exists and its
  344        *             <code>checkConnect</code> method doesn't allow the operation.
  345        * @exception  IllegalArgumentException if the port parameter is outside
  346        *             the specified range of valid port values, which is between
  347        *             0 and 65535, inclusive.
  348        * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  349        * @see        java.net.SocketImpl
  350        * @see        java.net.SocketImplFactory#createSocketImpl()
  351        * @see        SecurityManager#checkConnect
  352        * @deprecated Use DatagramSocket instead for UDP transport.
  353        */
  354       @Deprecated
  355       public Socket(String host, int port, boolean stream) throws IOException {
  356           this(host != null ? new InetSocketAddress(host, port) :
  357                  new InetSocketAddress(InetAddress.getByName(null), port),
  358                (SocketAddress) null, stream);
  359       }
  360   
  361       /**
  362        * Creates a socket and connects it to the specified port number at
  363        * the specified IP address.
  364        * <p>
  365        * If the stream argument is <code>true</code>, this creates a
  366        * stream socket. If the stream argument is <code>false</code>, it
  367        * creates a datagram socket.
  368        * <p>
  369        * If the application has specified a server socket factory, that
  370        * factory's <code>createSocketImpl</code> method is called to create
  371        * the actual socket implementation. Otherwise a "plain" socket is created.
  372        *
  373        * <p>If there is a security manager, its
  374        * <code>checkConnect</code> method is called
  375        * with <code>host.getHostAddress()</code> and <code>port</code>
  376        * as its arguments. This could result in a SecurityException.
  377        * <p>
  378        * If UDP socket is used, TCP/IP related socket options will not apply.
  379        *
  380        * @param      host     the IP address.
  381        * @param      port      the port number.
  382        * @param      stream    if <code>true</code>, create a stream socket;
  383        *                       otherwise, create a datagram socket.
  384        * @exception  IOException  if an I/O error occurs when creating the socket.
  385        * @exception  SecurityException  if a security manager exists and its
  386        *             <code>checkConnect</code> method doesn't allow the operation.
  387        * @exception  IllegalArgumentException if the port parameter is outside
  388        *             the specified range of valid port values, which is between
  389        *             0 and 65535, inclusive.
  390        * @exception  NullPointerException if <code>host</code> is null.
  391        * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
  392        * @see        java.net.SocketImpl
  393        * @see        java.net.SocketImplFactory#createSocketImpl()
  394        * @see        SecurityManager#checkConnect
  395        * @deprecated Use DatagramSocket instead for UDP transport.
  396        */
  397       @Deprecated
  398       public Socket(InetAddress host, int port, boolean stream) throws IOException {
  399           this(host != null ? new InetSocketAddress(host, port) : null,
  400                new InetSocketAddress(0), stream);
  401       }
  402   
  403       private Socket(SocketAddress address, SocketAddress localAddr,
  404                      boolean stream) throws IOException {
  405           setImpl();
  406   
  407           // backward compatibility
  408           if (address == null)
  409               throw new NullPointerException();
  410   
  411           try {
  412               createImpl(stream);
  413               if (localAddr != null)
  414                   bind(localAddr);
  415               if (address != null)
  416                   connect(address);
  417           } catch (IOException e) {
  418               close();
  419               throw e;
  420           }
  421       }
  422   
  423       /**
  424        * Creates the socket implementation.
  425        *
  426        * @param stream a <code>boolean</code> value : <code>true</code> for a TCP socket,
  427        *               <code>false</code> for UDP.
  428        * @throws IOException if creation fails
  429        * @since 1.4
  430        */
  431        void createImpl(boolean stream) throws SocketException {
  432           if (impl == null)
  433               setImpl();
  434           try {
  435               impl.create(stream);
  436               created = true;
  437           } catch (IOException e) {
  438               throw new SocketException(e.getMessage());
  439           }
  440       }
  441   
  442       private void checkOldImpl() {
  443           if (impl == null)
  444               return;
  445           // SocketImpl.connect() is a protected method, therefore we need to use
  446           // getDeclaredMethod, therefore we need permission to access the member
  447   
  448           oldImpl = AccessController.doPrivileged
  449                                   (new PrivilegedAction<Boolean>() {
  450               public Boolean run() {
  451                   Class[] cl = new Class[2];
  452                   cl[0] = SocketAddress.class;
  453                   cl[1] = Integer.TYPE;
  454                   Class clazz = impl.getClass();
  455                   while (true) {
  456                       try {
  457                           clazz.getDeclaredMethod("connect", cl);
  458                           return Boolean.FALSE;
  459                       } catch (NoSuchMethodException e) {
  460                           clazz = clazz.getSuperclass();
  461                           // java.net.SocketImpl class will always have this abstract method.
  462                           // If we have not found it by now in the hierarchy then it does not
  463                           // exist, we are an old style impl.
  464                           if (clazz.equals(java.net.SocketImpl.class)) {
  465                               return Boolean.TRUE;
  466                           }
  467                       }
  468                   }
  469               }
  470           });
  471       }
  472   
  473       /**
  474        * Sets impl to the system-default type of SocketImpl.
  475        * @since 1.4
  476        */
  477       void setImpl() {
  478           if (factory != null) {
  479               impl = factory.createSocketImpl();
  480               checkOldImpl();
  481           } else {
  482               // No need to do a checkOldImpl() here, we know it's an up to date
  483               // SocketImpl!
  484               impl = new SocksSocketImpl();
  485           }
  486           if (impl != null)
  487               impl.setSocket(this);
  488       }
  489   
  490   
  491       /**
  492        * Get the <code>SocketImpl</code> attached to this socket, creating
  493        * it if necessary.
  494        *
  495        * @return  the <code>SocketImpl</code> attached to that ServerSocket.
  496        * @throws SocketException if creation fails
  497        * @since 1.4
  498        */
  499       SocketImpl getImpl() throws SocketException {
  500           if (!created)
  501               createImpl(true);
  502           return impl;
  503       }
  504   
  505       /**
  506        * Connects this socket to the server.
  507        *
  508        * @param   endpoint the <code>SocketAddress</code>
  509        * @throws  IOException if an error occurs during the connection
  510        * @throws  java.nio.channels.IllegalBlockingModeException
  511        *          if this socket has an associated channel,
  512        *          and the channel is in non-blocking mode
  513        * @throws  IllegalArgumentException if endpoint is null or is a
  514        *          SocketAddress subclass not supported by this socket
  515        * @since 1.4
  516        * @spec JSR-51
  517        */
  518       public void connect(SocketAddress endpoint) throws IOException {
  519           connect(endpoint, 0);
  520       }
  521   
  522       /**
  523        * Connects this socket to the server with a specified timeout value.
  524        * A timeout of zero is interpreted as an infinite timeout. The connection
  525        * will then block until established or an error occurs.
  526        *
  527        * @param   endpoint the <code>SocketAddress</code>
  528        * @param   timeout  the timeout value to be used in milliseconds.
  529        * @throws  IOException if an error occurs during the connection
  530        * @throws  SocketTimeoutException if timeout expires before connecting
  531        * @throws  java.nio.channels.IllegalBlockingModeException
  532        *          if this socket has an associated channel,
  533        *          and the channel is in non-blocking mode
  534        * @throws  IllegalArgumentException if endpoint is null or is a
  535        *          SocketAddress subclass not supported by this socket
  536        * @since 1.4
  537        * @spec JSR-51
  538        */
  539       public void connect(SocketAddress endpoint, int timeout) throws IOException {
  540           if (endpoint == null)
  541               throw new IllegalArgumentException("connect: The address can't be null");
  542   
  543           if (timeout < 0)
  544             throw new IllegalArgumentException("connect: timeout can't be negative");
  545   
  546           if (isClosed())
  547               throw new SocketException("Socket is closed");
  548   
  549           if (!oldImpl && isConnected())
  550               throw new SocketException("already connected");
  551   
  552           if (!(endpoint instanceof InetSocketAddress))
  553               throw new IllegalArgumentException("Unsupported address type");
  554   
  555           InetSocketAddress epoint = (InetSocketAddress) endpoint;
  556   
  557           SecurityManager security = System.getSecurityManager();
  558           if (security != null) {
  559               if (epoint.isUnresolved())
  560                   security.checkConnect(epoint.getHostName(),
  561                                         epoint.getPort());
  562               else
  563                   security.checkConnect(epoint.getAddress().getHostAddress(),
  564                                         epoint.getPort());
  565           }
  566           if (!created)
  567               createImpl(true);
  568           if (!oldImpl)
  569               impl.connect(epoint, timeout);
  570           else if (timeout == 0) {
  571               if (epoint.isUnresolved())
  572                   impl.connect(epoint.getAddress().getHostName(),
  573                                epoint.getPort());
  574               else
  575                   impl.connect(epoint.getAddress(), epoint.getPort());
  576           } else
  577               throw new UnsupportedOperationException("SocketImpl.connect(addr, timeout)");
  578           connected = true;
  579           /*
  580            * If the socket was not bound before the connect, it is now because
  581            * the kernel will have picked an ephemeral port & a local address
  582            */
  583           bound = true;
  584       }
  585   
  586       /**
  587        * Binds the socket to a local address.
  588        * <P>
  589        * If the address is <code>null</code>, then the system will pick up
  590        * an ephemeral port and a valid local address to bind the socket.
  591        *
  592        * @param   bindpoint the <code>SocketAddress</code> to bind to
  593        * @throws  IOException if the bind operation fails, or if the socket
  594        *                     is already bound.
  595        * @throws  IllegalArgumentException if bindpoint is a
  596        *          SocketAddress subclass not supported by this socket
  597        *
  598        * @since   1.4
  599        * @see #isBound
  600        */
  601       public void bind(SocketAddress bindpoint) throws IOException {
  602           if (isClosed())
  603               throw new SocketException("Socket is closed");
  604           if (!oldImpl && isBound())
  605               throw new SocketException("Already bound");
  606   
  607           if (bindpoint != null && (!(bindpoint instanceof InetSocketAddress)))
  608               throw new IllegalArgumentException("Unsupported address type");
  609           InetSocketAddress epoint = (InetSocketAddress) bindpoint;
  610           if (epoint != null && epoint.isUnresolved())
  611               throw new SocketException("Unresolved address");
  612           if (bindpoint == null)
  613               getImpl().bind(InetAddress.anyLocalAddress(), 0);
  614           else
  615               getImpl().bind(epoint.getAddress(),
  616                              epoint.getPort());
  617           bound = true;
  618       }
  619   
  620       /**
  621        * set the flags after an accept() call.
  622        */
  623       final void postAccept() {
  624           connected = true;
  625           created = true;
  626           bound = true;
  627       }
  628   
  629       void setCreated() {
  630           created = true;
  631       }
  632   
  633       void setBound() {
  634           bound = true;
  635       }
  636   
  637       void setConnected() {
  638           connected = true;
  639       }
  640   
  641       /**
  642        * Returns the address to which the socket is connected.
  643        * <p>
  644        * If the socket was connected prior to being {@link #close closed},
  645        * then this method will continue to return the connected address
  646        * after the socket is closed.
  647        *
  648        * @return  the remote IP address to which this socket is connected,
  649        *          or <code>null</code> if the socket is not connected.
  650        */
  651       public InetAddress getInetAddress() {
  652           if (!isConnected())
  653               return null;
  654           try {
  655               return getImpl().getInetAddress();
  656           } catch (SocketException e) {
  657           }
  658           return null;
  659       }
  660   
  661       /**
  662        * Gets the local address to which the socket is bound.
  663        *
  664        * @return the local address to which the socket is bound, or
  665        *         the {@link InetAddress#isAnyLocalAddress wildcard} address
  666        *         if the socket is closed or not bound yet.
  667        * @since   JDK1.1
  668        */
  669       public InetAddress getLocalAddress() {
  670           // This is for backward compatibility
  671           if (!isBound())
  672               return InetAddress.anyLocalAddress();
  673           InetAddress in = null;
  674           try {
  675               in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
  676               if (in.isAnyLocalAddress()) {
  677                   in = InetAddress.anyLocalAddress();
  678               }
  679           } catch (Exception e) {
  680               in = InetAddress.anyLocalAddress(); // "0.0.0.0"
  681           }
  682           return in;
  683       }
  684   
  685       /**
  686        * Returns the remote port number to which this socket is connected.
  687        * <p>
  688        * If the socket was connected prior to being {@link #close closed},
  689        * then this method will continue to return the connected port number
  690        * after the socket is closed.
  691        *
  692        * @return  the remote port number to which this socket is connected, or
  693        *          0 if the socket is not connected yet.
  694        */
  695       public int getPort() {
  696           if (!isConnected())
  697               return 0;
  698           try {
  699               return getImpl().getPort();
  700           } catch (SocketException e) {
  701               // Shouldn't happen as we're connected
  702           }
  703           return -1;
  704       }
  705   
  706       /**
  707        * Returns the local port number to which this socket is bound.
  708        * <p>
  709        * If the socket was bound prior to being {@link #close closed},
  710        * then this method will continue to return the local port number
  711        * after the socket is closed.
  712        *
  713        * @return  the local port number to which this socket is bound or -1
  714        *          if the socket is not bound yet.
  715        */
  716       public int getLocalPort() {
  717           if (!isBound())
  718               return -1;
  719           try {
  720               return getImpl().getLocalPort();
  721           } catch(SocketException e) {
  722               // shouldn't happen as we're bound
  723           }
  724           return -1;
  725       }
  726   
  727       /**
  728        * Returns the address of the endpoint this socket is connected to, or
  729        * <code>null</code> if it is unconnected.
  730        * <p>
  731        * If the socket was connected prior to being {@link #close closed},
  732        * then this method will continue to return the connected address
  733        * after the socket is closed.
  734        *
  735   
  736        * @return a <code>SocketAddress</code> representing the remote endpoint of this
  737        *         socket, or <code>null</code> if it is not connected yet.
  738        * @see #getInetAddress()
  739        * @see #getPort()
  740        * @see #connect(SocketAddress, int)
  741        * @see #connect(SocketAddress)
  742        * @since 1.4
  743        */
  744       public SocketAddress getRemoteSocketAddress() {
  745           if (!isConnected())
  746               return null;
  747           return new InetSocketAddress(getInetAddress(), getPort());
  748       }
  749   
  750       /**
  751        * Returns the address of the endpoint this socket is bound to, or
  752        * <code>null</code> if it is not bound yet.
  753        * <p>
  754        * If a socket bound to an endpoint represented by an
  755        * <code>InetSocketAddress </code> is {@link #close closed},
  756        * then this method will continue to return an <code>InetSocketAddress</code>
  757        * after the socket is closed. In that case the returned
  758        * <code>InetSocketAddress</code>'s address is the
  759        * {@link InetAddress#isAnyLocalAddress wildcard} address
  760        * and its port is the local port that it was bound to.
  761        *
  762        * @return a <code>SocketAddress</code> representing the local endpoint of this
  763        *         socket, or <code>null</code> if it is not bound yet.
  764        * @see #getLocalAddress()
  765        * @see #getLocalPort()
  766        * @see #bind(SocketAddress)
  767        * @since 1.4
  768        */
  769   
  770       public SocketAddress getLocalSocketAddress() {
  771           if (!isBound())
  772               return null;
  773           return new InetSocketAddress(getLocalAddress(), getLocalPort());
  774       }
  775   
  776       /**
  777        * Returns the unique {@link java.nio.channels.SocketChannel SocketChannel}
  778        * object associated with this socket, if any.
  779        *
  780        * <p> A socket will have a channel if, and only if, the channel itself was
  781        * created via the {@link java.nio.channels.SocketChannel#open
  782        * SocketChannel.open} or {@link
  783        * java.nio.channels.ServerSocketChannel#accept ServerSocketChannel.accept}
  784        * methods.
  785        *
  786        * @return  the socket channel associated with this socket,
  787        *          or <tt>null</tt> if this socket was not created
  788        *          for a channel
  789        *
  790        * @since 1.4
  791        * @spec JSR-51
  792        */
  793       public SocketChannel getChannel() {
  794           return null;
  795       }
  796   
  797       /**
  798        * Returns an input stream for this socket.
  799        *
  800        * <p> If this socket has an associated channel then the resulting input
  801        * stream delegates all of its operations to the channel.  If the channel
  802        * is in non-blocking mode then the input stream's <tt>read</tt> operations
  803        * will throw an {@link java.nio.channels.IllegalBlockingModeException}.
  804        *
  805        * <p>Under abnormal conditions the underlying connection may be
  806        * broken by the remote host or the network software (for example
  807        * a connection reset in the case of TCP connections). When a
  808        * broken connection is detected by the network software the
  809        * following applies to the returned input stream :-
  810        *
  811        * <ul>
  812        *
  813        *   <li><p>The network software may discard bytes that are buffered
  814        *   by the socket. Bytes that aren't discarded by the network
  815        *   software can be read using {@link java.io.InputStream#read read}.
  816        *
  817        *   <li><p>If there are no bytes buffered on the socket, or all
  818        *   buffered bytes have been consumed by
  819        *   {@link java.io.InputStream#read read}, then all subsequent
  820        *   calls to {@link java.io.InputStream#read read} will throw an
  821        *   {@link java.io.IOException IOException}.
  822        *
  823        *   <li><p>If there are no bytes buffered on the socket, and the
  824        *   socket has not been closed using {@link #close close}, then
  825        *   {@link java.io.InputStream#available available} will
  826        *   return <code>0</code>.
  827        *
  828        * </ul>
  829        *
  830        * <p> Closing the returned {@link java.io.InputStream InputStream}
  831        * will close the associated socket.
  832        *
  833        * @return     an input stream for reading bytes from this socket.
  834        * @exception  IOException  if an I/O error occurs when creating the
  835        *             input stream, the socket is closed, the socket is
  836        *             not connected, or the socket input has been shutdown
  837        *             using {@link #shutdownInput()}
  838        *
  839        * @revised 1.4
  840        * @spec JSR-51
  841        */
  842       public InputStream getInputStream() throws IOException {
  843           if (isClosed())
  844               throw new SocketException("Socket is closed");
  845           if (!isConnected())
  846               throw new SocketException("Socket is not connected");
  847           if (isInputShutdown())
  848               throw new SocketException("Socket input is shutdown");
  849           final Socket s = this;
  850           InputStream is = null;
  851           try {
  852               is = AccessController.doPrivileged(
  853                   new PrivilegedExceptionAction<InputStream>() {
  854                       public InputStream run() throws IOException {
  855                           return impl.getInputStream();
  856                       }
  857                   });
  858           } catch (java.security.PrivilegedActionException e) {
  859               throw (IOException) e.getException();
  860           }
  861           return is;
  862       }
  863   
  864       /**
  865        * Returns an output stream for this socket.
  866        *
  867        * <p> If this socket has an associated channel then the resulting output
  868        * stream delegates all of its operations to the channel.  If the channel
  869        * is in non-blocking mode then the output stream's <tt>write</tt>
  870        * operations will throw an {@link
  871        * java.nio.channels.IllegalBlockingModeException}.
  872        *
  873        * <p> Closing the returned {@link java.io.OutputStream OutputStream}
  874        * will close the associated socket.
  875        *
  876        * @return     an output stream for writing bytes to this socket.
  877        * @exception  IOException  if an I/O error occurs when creating the
  878        *               output stream or if the socket is not connected.
  879        * @revised 1.4
  880        * @spec JSR-51
  881        */
  882       public OutputStream getOutputStream() throws IOException {
  883           if (isClosed())
  884               throw new SocketException("Socket is closed");
  885           if (!isConnected())
  886               throw new SocketException("Socket is not connected");
  887           if (isOutputShutdown())
  888               throw new SocketException("Socket output is shutdown");
  889           final Socket s = this;
  890           OutputStream os = null;
  891           try {
  892               os = AccessController.doPrivileged(
  893                   new PrivilegedExceptionAction<OutputStream>() {
  894                       public OutputStream run() throws IOException {
  895                           return impl.getOutputStream();
  896                       }
  897                   });
  898           } catch (java.security.PrivilegedActionException e) {
  899               throw (IOException) e.getException();
  900           }
  901           return os;
  902       }
  903   
  904       /**
  905        * Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
  906        *
  907        * @param on <code>true</code> to enable TCP_NODELAY,
  908        * <code>false</code> to disable.
  909        *
  910        * @exception SocketException if there is an error
  911        * in the underlying protocol, such as a TCP error.
  912        *
  913        * @since   JDK1.1
  914        *
  915        * @see #getTcpNoDelay()
  916        */
  917       public void setTcpNoDelay(boolean on) throws SocketException {
  918           if (isClosed())
  919               throw new SocketException("Socket is closed");
  920           getImpl().setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
  921       }
  922   
  923       /**
  924        * Tests if TCP_NODELAY is enabled.
  925        *
  926        * @return a <code>boolean</code> indicating whether or not TCP_NODELAY is enabled.
  927        * @exception SocketException if there is an error
  928        * in the underlying protocol, such as a TCP error.
  929        * @since   JDK1.1
  930        * @see #setTcpNoDelay(boolean)
  931        */
  932       public boolean getTcpNoDelay() throws SocketException {
  933           if (isClosed())
  934               throw new SocketException("Socket is closed");
  935           return ((Boolean) getImpl().getOption(SocketOptions.TCP_NODELAY)).booleanValue();
  936       }
  937   
  938       /**
  939        * Enable/disable SO_LINGER with the specified linger time in seconds.
  940        * The maximum timeout value is platform specific.
  941        *
  942        * The setting only affects socket close.
  943        *
  944        * @param on     whether or not to linger on.
  945        * @param linger how long to linger for, if on is true.
  946        * @exception SocketException if there is an error
  947        * in the underlying protocol, such as a TCP error.
  948        * @exception IllegalArgumentException if the linger value is negative.
  949        * @since JDK1.1
  950        * @see #getSoLinger()
  951        */
  952       public void setSoLinger(boolean on, int linger) throws SocketException {
  953           if (isClosed())
  954               throw new SocketException("Socket is closed");
  955           if (!on) {
  956               getImpl().setOption(SocketOptions.SO_LINGER, new Boolean(on));
  957           } else {
  958               if (linger < 0) {
  959                   throw new IllegalArgumentException("invalid value for SO_LINGER");
  960               }
  961               if (linger > 65535)
  962                   linger = 65535;
  963               getImpl().setOption(SocketOptions.SO_LINGER, new Integer(linger));
  964           }
  965       }
  966   
  967       /**
  968        * Returns setting for SO_LINGER. -1 returns implies that the
  969        * option is disabled.
  970        *
  971        * The setting only affects socket close.
  972        *
  973        * @return the setting for SO_LINGER.
  974        * @exception SocketException if there is an error
  975        * in the underlying protocol, such as a TCP error.
  976        * @since   JDK1.1
  977        * @see #setSoLinger(boolean, int)
  978        */
  979       public int getSoLinger() throws SocketException {
  980           if (isClosed())
  981               throw new SocketException("Socket is closed");
  982           Object o = getImpl().getOption(SocketOptions.SO_LINGER);
  983           if (o instanceof Integer) {
  984               return ((Integer) o).intValue();
  985           } else {
  986               return -1;
  987           }
  988       }
  989   
  990       /**
  991        * Send one byte of urgent data on the socket. The byte to be sent is the lowest eight
  992        * bits of the data parameter. The urgent byte is
  993        * sent after any preceding writes to the socket OutputStream
  994        * and before any future writes to the OutputStream.
  995        * @param data The byte of data to send
  996        * @exception IOException if there is an error
  997        *  sending the data.
  998        * @since 1.4
  999        */
 1000       public void sendUrgentData (int data) throws IOException  {
 1001           if (!getImpl().supportsUrgentData ()) {
 1002               throw new SocketException ("Urgent data not supported");
 1003           }
 1004           getImpl().sendUrgentData (data);
 1005       }
 1006   
 1007       /**
 1008        * Enable/disable OOBINLINE (receipt of TCP urgent data)
 1009        *
 1010        * By default, this option is disabled and TCP urgent data received on a
 1011        * socket is silently discarded. If the user wishes to receive urgent data, then
 1012        * this option must be enabled. When enabled, urgent data is received
 1013        * inline with normal data.
 1014        * <p>
 1015        * Note, only limited support is provided for handling incoming urgent
 1016        * data. In particular, no notification of incoming urgent data is provided
 1017        * and there is no capability to distinguish between normal data and urgent
 1018        * data unless provided by a higher level protocol.
 1019        *
 1020        * @param on <code>true</code> to enable OOBINLINE,
 1021        * <code>false</code> to disable.
 1022        *
 1023        * @exception SocketException if there is an error
 1024        * in the underlying protocol, such as a TCP error.
 1025        *
 1026        * @since   1.4
 1027        *
 1028        * @see #getOOBInline()
 1029        */
 1030       public void setOOBInline(boolean on) throws SocketException {
 1031           if (isClosed())
 1032               throw new SocketException("Socket is closed");
 1033           getImpl().setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(on));
 1034       }
 1035   
 1036       /**
 1037        * Tests if OOBINLINE is enabled.
 1038        *
 1039        * @return a <code>boolean</code> indicating whether or not OOBINLINE is enabled.
 1040        * @exception SocketException if there is an error
 1041        * in the underlying protocol, such as a TCP error.
 1042        * @since   1.4
 1043        * @see #setOOBInline(boolean)
 1044        */
 1045       public boolean getOOBInline() throws SocketException {
 1046           if (isClosed())
 1047               throw new SocketException("Socket is closed");
 1048           return ((Boolean) getImpl().getOption(SocketOptions.SO_OOBINLINE)).booleanValue();
 1049       }
 1050   
 1051       /**
 1052        *  Enable/disable SO_TIMEOUT with the specified timeout, in
 1053        *  milliseconds.  With this option set to a non-zero timeout,
 1054        *  a read() call on the InputStream associated with this Socket
 1055        *  will block for only this amount of time.  If the timeout expires,
 1056        *  a <B>java.net.SocketTimeoutException</B> is raised, though the
 1057        *  Socket is still valid. The option <B>must</B> be enabled
 1058        *  prior to entering the blocking operation to have effect. The
 1059        *  timeout must be > 0.
 1060        *  A timeout of zero is interpreted as an infinite timeout.
 1061        * @param timeout the specified timeout, in milliseconds.
 1062        * @exception SocketException if there is an error
 1063        * in the underlying protocol, such as a TCP error.
 1064        * @since   JDK 1.1
 1065        * @see #getSoTimeout()
 1066        */
 1067       public synchronized void setSoTimeout(int timeout) throws SocketException {
 1068           if (isClosed())
 1069               throw new SocketException("Socket is closed");
 1070           if (timeout < 0)
 1071             throw new IllegalArgumentException("timeout can't be negative");
 1072   
 1073           getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
 1074       }
 1075   
 1076       /**
 1077        * Returns setting for SO_TIMEOUT.  0 returns implies that the
 1078        * option is disabled (i.e., timeout of infinity).
 1079        * @return the setting for SO_TIMEOUT
 1080        * @exception SocketException if there is an error
 1081        * in the underlying protocol, such as a TCP error.
 1082        * @since   JDK1.1
 1083        * @see #setSoTimeout(int)
 1084        */
 1085       public synchronized int getSoTimeout() throws SocketException {
 1086           if (isClosed())
 1087               throw new SocketException("Socket is closed");
 1088           Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
 1089           /* extra type safety */
 1090           if (o instanceof Integer) {
 1091               return ((Integer) o).intValue();
 1092           } else {
 1093               return 0;
 1094           }
 1095       }
 1096   
 1097       /**
 1098        * Sets the SO_SNDBUF option to the specified value for this
 1099        * <tt>Socket</tt>. The SO_SNDBUF option is used by the platform's
 1100        * networking code as a hint for the size to set
 1101        * the underlying network I/O buffers.
 1102        *
 1103        * <p>Because SO_SNDBUF is a hint, applications that want to
 1104        * verify what size the buffers were set to should call
 1105        * {@link #getSendBufferSize()}.
 1106        *
 1107        * @exception SocketException if there is an error
 1108        * in the underlying protocol, such as a TCP error.
 1109        *
 1110        * @param size the size to which to set the send buffer
 1111        * size. This value must be greater than 0.
 1112        *
 1113        * @exception IllegalArgumentException if the
 1114        * value is 0 or is negative.
 1115        *
 1116        * @see #getSendBufferSize()
 1117        * @since 1.2
 1118        */
 1119       public synchronized void setSendBufferSize(int size)
 1120       throws SocketException{
 1121           if (!(size > 0)) {
 1122               throw new IllegalArgumentException("negative send size");
 1123           }
 1124           if (isClosed())
 1125               throw new SocketException("Socket is closed");
 1126           getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
 1127       }
 1128   
 1129       /**
 1130        * Get value of the SO_SNDBUF option for this <tt>Socket</tt>,
 1131        * that is the buffer size used by the platform
 1132        * for output on this <tt>Socket</tt>.
 1133        * @return the value of the SO_SNDBUF option for this <tt>Socket</tt>.
 1134        *
 1135        * @exception SocketException if there is an error
 1136        * in the underlying protocol, such as a TCP error.
 1137        *
 1138        * @see #setSendBufferSize(int)
 1139        * @since 1.2
 1140        */
 1141       public synchronized int getSendBufferSize() throws SocketException {
 1142           if (isClosed())
 1143               throw new SocketException("Socket is closed");
 1144           int result = 0;
 1145           Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
 1146           if (o instanceof Integer) {
 1147               result = ((Integer)o).intValue();
 1148           }
 1149           return result;
 1150       }
 1151   
 1152       /**
 1153        * Sets the SO_RCVBUF option to the specified value for this
 1154        * <tt>Socket</tt>. The SO_RCVBUF option is used by the platform's
 1155        * networking code as a hint for the size to set
 1156        * the underlying network I/O buffers.
 1157        *
 1158        * <p>Increasing the receive buffer size can increase the performance of
 1159        * network I/O for high-volume connection, while decreasing it can
 1160        * help reduce the backlog of incoming data.
 1161        *
 1162        * <p>Because SO_RCVBUF is a hint, applications that want to
 1163        * verify what size the buffers were set to should call
 1164        * {@link #getReceiveBufferSize()}.
 1165        *
 1166        * <p>The value of SO_RCVBUF is also used to set the TCP receive window
 1167        * that is advertized to the remote peer. Generally, the window size
 1168        * can be modified at any time when a socket is connected. However, if
 1169        * a receive window larger than 64K is required then this must be requested
 1170        * <B>before</B> the socket is connected to the remote peer. There are two
 1171        * cases to be aware of:<p>
 1172        * <ol>
 1173        * <li>For sockets accepted from a ServerSocket, this must be done by calling
 1174        * {@link ServerSocket#setReceiveBufferSize(int)} before the ServerSocket
 1175        * is bound to a local address.<p></li>
 1176        * <li>For client sockets, setReceiveBufferSize() must be called before
 1177        * connecting the socket to its remote peer.<p></li></ol>
 1178        * @param size the size to which to set the receive buffer
 1179        * size. This value must be greater than 0.
 1180        *
 1181        * @exception IllegalArgumentException if the value is 0 or is
 1182        * negative.
 1183        *
 1184        * @exception SocketException if there is an error
 1185        * in the underlying protocol, such as a TCP error.
 1186        *
 1187        * @see #getReceiveBufferSize()
 1188        * @see ServerSocket#setReceiveBufferSize(int)
 1189        * @since 1.2
 1190        */
 1191       public synchronized void setReceiveBufferSize(int size)
 1192       throws SocketException{
 1193           if (size <= 0) {
 1194               throw new IllegalArgumentException("invalid receive size");
 1195           }
 1196           if (isClosed())
 1197               throw new SocketException("Socket is closed");
 1198           getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
 1199       }
 1200   
 1201       /**
 1202        * Gets the value of the SO_RCVBUF option for this <tt>Socket</tt>,
 1203        * that is the buffer size used by the platform for
 1204        * input on this <tt>Socket</tt>.
 1205        *
 1206        * @return the value of the SO_RCVBUF option for this <tt>Socket</tt>.
 1207        * @exception SocketException if there is an error
 1208        * in the underlying protocol, such as a TCP error.
 1209        * @see #setReceiveBufferSize(int)
 1210        * @since 1.2
 1211        */
 1212       public synchronized int getReceiveBufferSize()
 1213       throws SocketException{
 1214           if (isClosed())
 1215               throw new SocketException("Socket is closed");
 1216           int result = 0;
 1217           Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
 1218           if (o instanceof Integer) {
 1219               result = ((Integer)o).intValue();
 1220           }
 1221           return result;
 1222       }
 1223   
 1224       /**
 1225        * Enable/disable SO_KEEPALIVE.
 1226        *
 1227        * @param on     whether or not to have socket keep alive turned on.
 1228        * @exception SocketException if there is an error
 1229        * in the underlying protocol, such as a TCP error.
 1230        * @since 1.3
 1231        * @see #getKeepAlive()
 1232        */
 1233       public void setKeepAlive(boolean on) throws SocketException {
 1234           if (isClosed())
 1235               throw new SocketException("Socket is closed");
 1236           getImpl().setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(on));
 1237       }
 1238   
 1239       /**
 1240        * Tests if SO_KEEPALIVE is enabled.
 1241        *
 1242        * @return a <code>boolean</code> indicating whether or not SO_KEEPALIVE is enabled.
 1243        * @exception SocketException if there is an error
 1244        * in the underlying protocol, such as a TCP error.
 1245        * @since   1.3
 1246        * @see #setKeepAlive(boolean)
 1247        */
 1248       public boolean getKeepAlive() throws SocketException {
 1249           if (isClosed())
 1250               throw new SocketException("Socket is closed");
 1251           return ((Boolean) getImpl().getOption(SocketOptions.SO_KEEPALIVE)).booleanValue();
 1252       }
 1253   
 1254       /**
 1255        * Sets traffic class or type-of-service octet in the IP
 1256        * header for packets sent from this Socket.
 1257        * As the underlying network implementation may ignore this
 1258        * value applications should consider it a hint.
 1259        *
 1260        * <P> The tc <B>must</B> be in the range <code> 0 <= tc <=
 1261        * 255</code> or an IllegalArgumentException will be thrown.
 1262        * <p>Notes:
 1263        * <p>For Internet Protocol v4 the value consists of an
 1264        * <code>integer</code>, the least significant 8 bits of which
 1265        * represent the value of the TOS octet in IP packets sent by
 1266        * the socket.
 1267        * RFC 1349 defines the TOS values as follows:
 1268        * <p>
 1269        * <UL>
 1270        * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
 1271        * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
 1272        * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
 1273        * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
 1274        * </UL>
 1275        * The last low order bit is always ignored as this
 1276        * corresponds to the MBZ (must be zero) bit.
 1277        * <p>
 1278        * Setting bits in the precedence field may result in a
 1279        * SocketException indicating that the operation is not
 1280        * permitted.
 1281        * <p>
 1282        * As RFC 1122 section 4.2.4.2 indicates, a compliant TCP
 1283        * implementation should, but is not required to, let application
 1284        * change the TOS field during the lifetime of a connection.
 1285        * So whether the type-of-service field can be changed after the
 1286        * TCP connection has been established depends on the implementation
 1287        * in the underlying platform. Applications should not assume that
 1288        * they can change the TOS field after the connection.
 1289        * <p>
 1290        * For Internet Protocol v6 <code>tc</code> is the value that
 1291        * would be placed into the sin6_flowinfo field of the IP header.
 1292        *
 1293        * @param tc        an <code>int</code> value for the bitset.
 1294        * @throws SocketException if there is an error setting the
 1295        * traffic class or type-of-service
 1296        * @since 1.4
 1297        * @see #getTrafficClass
 1298        */
 1299       public void setTrafficClass(int tc) throws SocketException {
 1300           if (tc < 0 || tc > 255)
 1301               throw new IllegalArgumentException("tc is not in range 0 -- 255");
 1302   
 1303           if (isClosed())
 1304               throw new SocketException("Socket is closed");
 1305           getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
 1306       }
 1307   
 1308       /**
 1309        * Gets traffic class or type-of-service in the IP header
 1310        * for packets sent from this Socket
 1311        * <p>
 1312        * As the underlying network implementation may ignore the
 1313        * traffic class or type-of-service set using {@link #setTrafficClass(int)}
 1314        * this method may return a different value than was previously
 1315        * set using the {@link #setTrafficClass(int)} method on this Socket.
 1316        *
 1317        * @return the traffic class or type-of-service already set
 1318        * @throws SocketException if there is an error obtaining the
 1319        * traffic class or type-of-service value.
 1320        * @since 1.4
 1321        * @see #setTrafficClass(int)
 1322        */
 1323       public int getTrafficClass() throws SocketException {
 1324           return ((Integer) (getImpl().getOption(SocketOptions.IP_TOS))).intValue();
 1325       }
 1326   
 1327       /**
 1328        * Enable/disable the SO_REUSEADDR socket option.
 1329        * <p>
 1330        * When a TCP connection is closed the connection may remain
 1331        * in a timeout state for a period of time after the connection
 1332        * is closed (typically known as the <tt>TIME_WAIT</tt> state
 1333        * or <tt>2MSL</tt> wait state).
 1334        * For applications using a well known socket address or port
 1335        * it may not be possible to bind a socket to the required
 1336        * <tt>SocketAddress</tt> if there is a connection in the
 1337        * timeout state involving the socket address or port.
 1338        * <p>
 1339        * Enabling <tt>SO_REUSEADDR</tt> prior to binding the socket
 1340        * using {@link #bind(SocketAddress)} allows the socket to be
 1341        * bound even though a previous connection is in a timeout
 1342        * state.
 1343        * <p>
 1344        * When a <tt>Socket</tt> is created the initial setting
 1345        * of <tt>SO_REUSEADDR</tt> is disabled.
 1346        * <p>
 1347        * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
 1348        * disabled after a socket is bound (See {@link #isBound()})
 1349        * is not defined.
 1350        *
 1351        * @param on  whether to enable or disable the socket option
 1352        * @exception SocketException if an error occurs enabling or
 1353        *            disabling the <tt>SO_RESUEADDR</tt> socket option,
 1354        *            or the socket is closed.
 1355        * @since 1.4
 1356        * @see #getReuseAddress()
 1357        * @see #bind(SocketAddress)
 1358        * @see #isClosed()
 1359        * @see #isBound()
 1360        */
 1361       public void setReuseAddress(boolean on) throws SocketException {
 1362           if (isClosed())
 1363               throw new SocketException("Socket is closed");
 1364           getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
 1365       }
 1366   
 1367       /**
 1368        * Tests if SO_REUSEADDR is enabled.
 1369        *
 1370        * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
 1371        * @exception SocketException if there is an error
 1372        * in the underlying protocol, such as a TCP error.
 1373        * @since   1.4
 1374        * @see #setReuseAddress(boolean)
 1375        */
 1376       public boolean getReuseAddress() throws SocketException {
 1377           if (isClosed())
 1378               throw new SocketException("Socket is closed");
 1379           return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
 1380       }
 1381   
 1382       /**
 1383        * Closes this socket.
 1384        * <p>
 1385        * Any thread currently blocked in an I/O operation upon this socket
 1386        * will throw a {@link SocketException}.
 1387        * <p>
 1388        * Once a socket has been closed, it is not available for further networking
 1389        * use (i.e. can't be reconnected or rebound). A new socket needs to be
 1390        * created.
 1391        *
 1392        * <p> Closing this socket will also close the socket's
 1393        * {@link java.io.InputStream InputStream} and
 1394        * {@link java.io.OutputStream OutputStream}.
 1395        *
 1396        * <p> If this socket has an associated channel then the channel is closed
 1397        * as well.
 1398        *
 1399        * @exception  IOException  if an I/O error occurs when closing this socket.
 1400        * @revised 1.4
 1401        * @spec JSR-51
 1402        * @see #isClosed
 1403        */
 1404       public synchronized void close() throws IOException {
 1405           synchronized(closeLock) {
 1406               if (isClosed())
 1407                   return;
 1408               if (created)
 1409                   impl.close();
 1410               closed = true;
 1411           }
 1412       }
 1413   
 1414       /**
 1415        * Places the input stream for this socket at "end of stream".
 1416        * Any data sent to the input stream side of the socket is acknowledged
 1417        * and then silently discarded.
 1418        * <p>
 1419        * If you read from a socket input stream after invoking
 1420        * shutdownInput() on the socket, the stream will return EOF.
 1421        *
 1422        * @exception IOException if an I/O error occurs when shutting down this
 1423        * socket.
 1424        *
 1425        * @since 1.3
 1426        * @see java.net.Socket#shutdownOutput()
 1427        * @see java.net.Socket#close()
 1428        * @see java.net.Socket#setSoLinger(boolean, int)
 1429        * @see #isInputShutdown
 1430        */
 1431       public void shutdownInput() throws IOException
 1432       {
 1433           if (isClosed())
 1434               throw new SocketException("Socket is closed");
 1435           if (!isConnected())
 1436               throw new SocketException("Socket is not connected");
 1437           if (isInputShutdown())
 1438               throw new SocketException("Socket input is already shutdown");
 1439           getImpl().shutdownInput();
 1440           shutIn = true;
 1441       }
 1442   
 1443       /**
 1444        * Disables the output stream for this socket.
 1445        * For a TCP socket, any previously written data will be sent
 1446        * followed by TCP's normal connection termination sequence.
 1447        *
 1448        * If you write to a socket output stream after invoking
 1449        * shutdownOutput() on the socket, the stream will throw
 1450        * an IOException.
 1451        *
 1452        * @exception IOException if an I/O error occurs when shutting down this
 1453        * socket.
 1454        *
 1455        * @since 1.3
 1456        * @see java.net.Socket#shutdownInput()
 1457        * @see java.net.Socket#close()
 1458        * @see java.net.Socket#setSoLinger(boolean, int)
 1459        * @see #isOutputShutdown
 1460        */
 1461       public void shutdownOutput() throws IOException
 1462       {
 1463           if (isClosed())
 1464               throw new SocketException("Socket is closed");
 1465           if (!isConnected())
 1466               throw new SocketException("Socket is not connected");
 1467           if (isOutputShutdown())
 1468               throw new SocketException("Socket output is already shutdown");
 1469           getImpl().shutdownOutput();
 1470           shutOut = true;
 1471       }
 1472   
 1473       /**
 1474        * Converts this socket to a <code>String</code>.
 1475        *
 1476        * @return  a string representation of this socket.
 1477        */
 1478       public String toString() {
 1479           try {
 1480               if (isConnected())
 1481                   return "Socket[addr=" + getImpl().getInetAddress() +
 1482                       ",port=" + getImpl().getPort() +
 1483                       ",localport=" + getImpl().getLocalPort() + "]";
 1484           } catch (SocketException e) {
 1485           }
 1486           return "Socket[unconnected]";
 1487       }
 1488   
 1489       /**
 1490        * Returns the connection state of the socket.
 1491        * <p>
 1492        * Note: Closing a socket doesn't clear its connection state, which means
 1493        * this method will return <code>true</code> for a closed socket
 1494        * (see {@link #isClosed()}) if it was successfuly connected prior
 1495        * to being closed.
 1496        *
 1497        * @return true if the socket was successfuly connected to a server
 1498        * @since 1.4
 1499        */
 1500       public boolean isConnected() {
 1501           // Before 1.3 Sockets were always connected during creation
 1502           return connected || oldImpl;
 1503       }
 1504   
 1505       /**
 1506        * Returns the binding state of the socket.
 1507        * <p>
 1508        * Note: Closing a socket doesn't clear its binding state, which means
 1509        * this method will return <code>true</code> for a closed socket
 1510        * (see {@link #isClosed()}) if it was successfuly bound prior
 1511        * to being closed.
 1512        *
 1513        * @return true if the socket was successfuly bound to an address
 1514        * @since 1.4
 1515        * @see #bind
 1516        */
 1517       public boolean isBound() {
 1518           // Before 1.3 Sockets were always bound during creation
 1519           return bound || oldImpl;
 1520       }
 1521   
 1522       /**
 1523        * Returns the closed state of the socket.
 1524        *
 1525        * @return true if the socket has been closed
 1526        * @since 1.4
 1527        * @see #close
 1528        */
 1529       public boolean isClosed() {
 1530           synchronized(closeLock) {
 1531               return closed;
 1532           }
 1533       }
 1534   
 1535       /**
 1536        * Returns whether the read-half of the socket connection is closed.
 1537        *
 1538        * @return true if the input of the socket has been shutdown
 1539        * @since 1.4
 1540        * @see #shutdownInput
 1541        */
 1542       public boolean isInputShutdown() {
 1543           return shutIn;
 1544       }
 1545   
 1546       /**
 1547        * Returns whether the write-half of the socket connection is closed.
 1548        *
 1549        * @return true if the output of the socket has been shutdown
 1550        * @since 1.4
 1551        * @see #shutdownOutput
 1552        */
 1553       public boolean isOutputShutdown() {
 1554           return shutOut;
 1555       }
 1556   
 1557       /**
 1558        * The factory for all client sockets.
 1559        */
 1560       private static SocketImplFactory factory = null;
 1561   
 1562       /**
 1563        * Sets the client socket implementation factory for the
 1564        * application. The factory can be specified only once.
 1565        * <p>
 1566        * When an application creates a new client socket, the socket
 1567        * implementation factory's <code>createSocketImpl</code> method is
 1568        * called to create the actual socket implementation.
 1569        * <p>
 1570        * Passing <code>null</code> to the method is a no-op unless the factory
 1571        * was already set.
 1572        * <p>If there is a security manager, this method first calls
 1573        * the security manager's <code>checkSetFactory</code> method
 1574        * to ensure the operation is allowed.
 1575        * This could result in a SecurityException.
 1576        *
 1577        * @param      fac   the desired factory.
 1578        * @exception  IOException  if an I/O error occurs when setting the
 1579        *               socket factory.
 1580        * @exception  SocketException  if the factory is already defined.
 1581        * @exception  SecurityException  if a security manager exists and its
 1582        *             <code>checkSetFactory</code> method doesn't allow the operation.
 1583        * @see        java.net.SocketImplFactory#createSocketImpl()
 1584        * @see        SecurityManager#checkSetFactory
 1585        */
 1586       public static synchronized void setSocketImplFactory(SocketImplFactory fac)
 1587           throws IOException
 1588       {
 1589           if (factory != null) {
 1590               throw new SocketException("factory already defined");
 1591           }
 1592           SecurityManager security = System.getSecurityManager();
 1593           if (security != null) {
 1594               security.checkSetFactory();
 1595           }
 1596           factory = fac;
 1597       }
 1598   
 1599       /**
 1600        * Sets performance preferences for this socket.
 1601        *
 1602        * <p> Sockets use the TCP/IP protocol by default.  Some implementations
 1603        * may offer alternative protocols which have different performance
 1604        * characteristics than TCP/IP.  This method allows the application to
 1605        * express its own preferences as to how these tradeoffs should be made
 1606        * when the implementation chooses from the available protocols.
 1607        *
 1608        * <p> Performance preferences are described by three integers
 1609        * whose values indicate the relative importance of short connection time,
 1610        * low latency, and high bandwidth.  The absolute values of the integers
 1611        * are irrelevant; in order to choose a protocol the values are simply
 1612        * compared, with larger values indicating stronger preferences. Negative
 1613        * values represent a lower priority than positive values. If the
 1614        * application prefers short connection time over both low latency and high
 1615        * bandwidth, for example, then it could invoke this method with the values
 1616        * <tt>(1, 0, 0)</tt>.  If the application prefers high bandwidth above low
 1617        * latency, and low latency above short connection time, then it could
 1618        * invoke this method with the values <tt>(0, 1, 2)</tt>.
 1619        *
 1620        * <p> Invoking this method after this socket has been connected
 1621        * will have no effect.
 1622        *
 1623        * @param  connectionTime
 1624        *         An <tt>int</tt> expressing the relative importance of a short
 1625        *         connection time
 1626        *
 1627        * @param  latency
 1628        *         An <tt>int</tt> expressing the relative importance of low
 1629        *         latency
 1630        *
 1631        * @param  bandwidth
 1632        *         An <tt>int</tt> expressing the relative importance of high
 1633        *         bandwidth
 1634        *
 1635        * @since 1.5
 1636        */
 1637       public void setPerformancePreferences(int connectionTime,
 1638                                             int latency,
 1639                                             int bandwidth)
 1640       {
 1641           /* Not implemented yet */
 1642       }
 1643   }

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