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