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