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