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

Save This Page
Home » openjdk-7 » java » net » [javadoc | source]