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