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