PageRenderTime 83ms CodeModel.GetById 3ms app.highlight 36ms RepoModel.GetById 32ms app.codeStats 0ms

/src/share/classes/java/net/Socket.java

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