/* Socket.java -- Client socket implementation
   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.net;

import gnu.java.net.PlainSocketImpl;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.SocketChannel;


/* Written using on-line Java Platform 1.2 API Specification.
 * Status:  I believe all methods are implemented.
 */

/**
 * This class models a client site socket.  A socket is a TCP/IP endpoint
 * for network communications conceptually similar to a file handle.
 * <p>
 * This class does not actually do any work.  Instead, it redirects all of
 * its calls to a socket implementation object which implements the
 * <code>SocketImpl</code> interface.  The implementation class is
 * instantiated by factory class that implements the
 * <code>SocketImplFactory interface</code>.  A default
 * factory is provided, however the factory may be set by a call to
 * the <code>setSocketImplFactory</code> method.  Note that this may only be
 * done once per virtual machine.  If a subsequent attempt is made to set the
 * factory, a <code>SocketException</code> will be thrown.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Per Bothner (bothner@cygnus.com)
 */
public class Socket
{
  /**
   * This is the user SocketImplFactory for this class.  If this variable is
   * null, a default factory is used.
   */
  static SocketImplFactory factory;

  /**
   * The implementation object to which calls are redirected
   */
  // package-private because ServerSocket.implAccept() needs to access it.
  SocketImpl impl;

  /**
   * True if socket implementation was created by calling their
   * create() method.
   */
  // package-private because ServerSocket.implAccept() needs to access it.
  boolean implCreated;

  /**
   * True if the socket is bound.
   * Package private so it can be set from ServerSocket when accept is called.
   */
  boolean bound;

  /**
   * True if input is shutdown.
   */
  private boolean inputShutdown;

  /**
   * True if output is shutdown.
   */
  private boolean outputShutdown;

  /**
   * Initializes a new instance of <code>Socket</code> object without
   * connecting to a remote host.  This useful for subclasses of socket that
   * might want this behavior.
   *
   * @specnote This constructor is public since JDK 1.4
   * @since 1.1
   */
  public Socket()
  {
    if (factory != null)
      impl = factory.createSocketImpl();
    else
      impl = new PlainSocketImpl();
  }

  /**
   * Initializes a new instance of <code>Socket</code> object without
   * connecting to a remote host.  This is useful for subclasses of socket
   * that might want this behavior.
   * <p>
   * Additionally, this socket will be created using the supplied
   * implementation class instead the default class or one returned by a
   * factory.  If this value is <code>null</code>, the default Socket
   * implementation is used.
   *
   * @param impl The <code>SocketImpl</code> to use for this
   *             <code>Socket</code>
   *
   * @exception SocketException If an error occurs
   *
   * @since 1.1
   */
  protected Socket(SocketImpl impl) throws SocketException
  {
    if (impl == null)
      this.impl = new PlainSocketImpl();
    else
      this.impl = impl;
  }

  /**
   * Initializes a new instance of <code>Socket</code> and connects to the
   * hostname and port specified as arguments.
   *
   * @param host The name of the host to connect to
   * @param port The port number to connect to
   *
   * @exception UnknownHostException If the hostname cannot be resolved to a
   * network address.
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkConnect method doesn't allow the operation
   */
  public Socket(String host, int port)
    throws UnknownHostException, IOException
  {
    this(InetAddress.getByName(host), port, null, 0, true);
  }

  /**
   * Initializes a new instance of <code>Socket</code> and connects to the
   * address and port number specified as arguments.
   *
   * @param address The address to connect to
   * @param port The port number to connect to
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkConnect method doesn't allow the operation
   */
  public Socket(InetAddress address, int port) throws IOException
  {
    this(address, port, null, 0, true);
  }

  /**
   * Initializes a new instance of <code>Socket</code> that connects to the
   * named host on the specified port and binds to the specified local address
   * and port.
   *
   * @param host The name of the remote host to connect to.
   * @param port The remote port to connect to.
   * @param localAddr The local address to bind to.
   * @param localPort The local port to bind to.
   *
   * @exception SecurityException If the <code>SecurityManager</code>
   * exists and does not allow a connection to the specified host/port or
   * binding to the specified local host/port.
   * @exception IOException If a connection error occurs.
   *
   * @since 1.1
   */
  public Socket(String host, int port, InetAddress localAddr, int localPort)
    throws IOException
  {
    this(InetAddress.getByName(host), port, localAddr, localPort, true);
  }

  /**
   * Initializes a new instance of <code>Socket</code> and connects to the
   * address and port number specified as arguments, plus binds to the
   * specified local address and port.
   *
   * @param address The remote address to connect to
   * @param port The remote port to connect to
   * @param localAddr The local address to connect to
   * @param localPort The local port to connect to
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkConnect method doesn't allow the operation
   *
   * @since 1.1
   */
  public Socket(InetAddress address, int port, InetAddress localAddr,
                int localPort) throws IOException
  {
    this(address, port, localAddr, localPort, true);
  }

  /**
   * Initializes a new instance of <code>Socket</code> and connects to the
   * hostname and port specified as arguments.  If the stream argument is set
   * to <code>true</code>, then a stream socket is created.  If it is
   * <code>false</code>, a datagram socket is created.
   *
   * @param host The name of the host to connect to
   * @param port The port to connect to
   * @param stream <code>true</code> for a stream socket, <code>false</code>
   * for a datagram socket
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkConnect method doesn't allow the operation
   *
   * @deprecated Use the <code>DatagramSocket</code> class to create
   * datagram oriented sockets.
   */
  public Socket(String host, int port, boolean stream)
    throws IOException
  {
    this(InetAddress.getByName(host), port, null, 0, stream);
  }

  /**
   * Initializes a new instance of <code>Socket</code> and connects to the
   * address and port number specified as arguments.  If the stream param is
   * <code>true</code>, a stream socket will be created, otherwise a datagram
   * socket is created.
   *
   * @param host The address to connect to
   * @param port The port number to connect to
   * @param stream <code>true</code> to create a stream socket,
   * <code>false</code> to create a datagram socket.
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkConnect method doesn't allow the operation
   *
   * @deprecated Use the <code>DatagramSocket</code> class to create
   * datagram oriented sockets.
   */
  public Socket(InetAddress host, int port, boolean stream)
    throws IOException
  {
    this(host, port, null, 0, stream);
  }

  /**
   * This constructor is where the real work takes place.  Connect to the
   * specified address and port.  Use default local values if not specified,
   * otherwise use the local host and port passed in.  Create as stream or
   * datagram based on "stream" argument.
   * <p>
   *
   * @param raddr The remote address to connect to
   * @param rport The remote port to connect to
   * @param laddr The local address to connect to
   * @param lport The local port to connect to
   * @param stream true for a stream socket, false for a datagram socket
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkConnect method doesn't allow the operation
   */
  private Socket(InetAddress raddr, int rport, InetAddress laddr, int lport,
                 boolean stream) throws IOException
  {
    this();

    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkConnect(raddr.getHostName(), rport);

    // bind socket
    SocketAddress bindaddr =
      laddr == null ? null : new InetSocketAddress(laddr, lport);
    bind(bindaddr);

    // connect socket
    connect(new InetSocketAddress(raddr, rport));

    // FIXME: JCL p. 1586 says if localPort is unspecified, bind to any port,
    // i.e. '0' and if localAddr is unspecified, use getLocalAddress() as
    // that default.  JDK 1.2 doc infers not to do a bind.
  }

  private SocketImpl getImpl() throws SocketException
  {
    try
      {
	if (! implCreated)
	  {
	    impl.create(true);
	    implCreated = true;
	  }
      }
    catch (IOException e)
      {
	SocketException se = new SocketException(e.toString());
	se.initCause(e);
	throw se;
      }

    return impl;
  }

  /**
   * Binds the socket to the givent local address/port
   *
   * @param bindpoint The address/port to bind to
   *
   * @exception IOException If an error occurs
   * @exception SecurityException If a security manager exists and its
   * checkConnect method doesn't allow the operation
   * @exception IllegalArgumentException If the address type is not supported
   *
   * @since 1.4
   */
  public void bind(SocketAddress bindpoint) throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    // XXX: JDK 1.4.1 API documentation says that if bindpoint is null the
    // socket will be bound to an ephemeral port and a valid local address.
    if (bindpoint == null)
      bindpoint = new InetSocketAddress(InetAddress.ANY_IF, 0);

    if (! (bindpoint instanceof InetSocketAddress))
      throw new IllegalArgumentException();

    InetSocketAddress tmp = (InetSocketAddress) bindpoint;

    // bind to address/port
    try
      {
	getImpl().bind(tmp.getAddress(), tmp.getPort());
	bound = true;
      }
    catch (IOException exception)
      {
	close();
	throw exception;
      }
    catch (RuntimeException exception)
      {
	close();
	throw exception;
      }
    catch (Error error)
      {
	close();
	throw error;
      }
  }

  /**
   * Connects the socket with a remote address.
   *
   * @param endpoint The address to connect to
   *
   * @exception IOException If an error occurs
   * @exception IllegalArgumentException If the addess type is not supported
   * @exception IllegalBlockingModeException If this socket has an associated
   * channel, and the channel is in non-blocking mode
   *
   * @since 1.4
   */
  public void connect(SocketAddress endpoint) throws IOException
  {
    connect(endpoint, 0);
  }

  /**
   * Connects the socket with a remote address. A timeout of zero is
   * interpreted as an infinite timeout. The connection will then block
   * until established or an error occurs.
   *
   * @param endpoint The address to connect to
   * @param timeout The length of the timeout in milliseconds, or
   * 0 to indicate no timeout.
   *
   * @exception IOException If an error occurs
   * @exception IllegalArgumentException If the address type is not supported
   * @exception IllegalBlockingModeException If this socket has an associated
   * channel, and the channel is in non-blocking mode
   * @exception SocketTimeoutException If the timeout is reached
   *
   * @since 1.4
   */
  public void connect(SocketAddress endpoint, int timeout)
    throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    if (! (endpoint instanceof InetSocketAddress))
      throw new IllegalArgumentException("unsupported address type");

    // The Sun spec says that if we have an associated channel and
    // it is in non-blocking mode, we throw an IllegalBlockingModeException.
    // However, in our implementation if the channel itself initiated this
    // operation, then we must honor it regardless of its blocking mode.
    if (getChannel() != null && ! getChannel().isBlocking()
        && ! ((PlainSocketImpl) getImpl()).isInChannelOperation())
      throw new IllegalBlockingModeException();

    if (! isBound())
      bind(null);

    getImpl().connect(endpoint, timeout);
  }

  /**
   * Returns the address of the remote end of the socket.  If this socket
   * is not connected, then <code>null</code> is returned.
   *
   * @return The remote address this socket is connected to
   */
  public InetAddress getInetAddress()
  {
    if (! isConnected())
      return null;

    try
      {
	return getImpl().getInetAddress();
      }
    catch (SocketException e)
      {
	// This cannot happen as we are connected.
      }

    return null;
  }

  /**
   * Returns the local address to which this socket is bound.  If this socket
   * is not connected, then a wildcard address, for which
   * @see InetAddress#isAnyLocalAddress() is <code>true</code>, is returned.
   *
   * @return The local address
   *
   * @since 1.1
   */
  public InetAddress getLocalAddress()
  {
    if (! isBound())
      return InetAddress.ANY_IF;

    InetAddress addr = null;

    try
      {
	addr = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
      }
    catch (SocketException e)
      {
	// (hopefully) shouldn't happen
	// throw new java.lang.InternalError
	//      ("Error in PlainSocketImpl.getOption");
	return null;
      }

    // FIXME: According to libgcj, checkConnect() is supposed to be called
    // before performing this operation.  Problems: 1) We don't have the
    // addr until after we do it, so we do a post check.  2). The docs I
    // see don't require this in the Socket case, only DatagramSocket, but
    // we'll assume they mean both.
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkConnect(addr.getHostName(), getLocalPort());

    return addr;
  }

  /**
   * Returns the port number of the remote end of the socket connection.  If
   * this socket is not connected, then 0 is returned.
   *
   * @return The remote port this socket is connected to
   */
  public int getPort()
  {
    if (! isConnected())
      return 0;

    try
      {
	return getImpl().getPort();
      }
    catch (SocketException e)
      {
	// This cannot happen as we are connected.
      }

    return 0;
  }

  /**
   * Returns the local port number to which this socket is bound.  If this
   * socket is not connected, then -1 is returned.
   *
   * @return The local port
   */
  public int getLocalPort()
  {
    if (! isBound())
      return -1;

    try
      {
	if (getImpl() != null)
	  return getImpl().getLocalPort();
      }
    catch (SocketException e)
      {
	// This cannot happen as we are bound.
      }

    return -1;
  }

  /**
   * Returns local socket address.
   *
   * @return the local socket address, null if not bound
   *
   * @since 1.4
   */
  public SocketAddress getLocalSocketAddress()
  {
    if (! isBound())
      return null;

    InetAddress addr = getLocalAddress();

    try
      {
	return new InetSocketAddress(addr, getImpl().getLocalPort());
      }
    catch (SocketException e)
      {
	// This cannot happen as we are bound.
	return null;
      }
  }

  /**
   * Returns the remote socket address.
   *
   * @return the remote socket address, null of not connected
   *
   * @since 1.4
   */
  public SocketAddress getRemoteSocketAddress()
  {
    if (! isConnected())
      return null;

    try
      {
	return new InetSocketAddress(getImpl().getInetAddress(),
	                             getImpl().getPort());
      }
    catch (SocketException e)
      {
	// This cannot happen as we are connected.
	return null;
      }
  }

  /**
   * Returns an InputStream for reading from this socket.
   *
   * @return The InputStream object
   *
   * @exception IOException If an error occurs or Socket is not connected
   */
  public InputStream getInputStream() throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    if (! isConnected())
      throw new IOException("not connected");

    return getImpl().getInputStream();
  }

  /**
   * Returns an OutputStream for writing to this socket.
   *
   * @return The OutputStream object
   *
   * @exception IOException If an error occurs or Socket is not connected
   */
  public OutputStream getOutputStream() throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    if (! isConnected())
      throw new IOException("not connected");

    return getImpl().getOutputStream();
  }

  /**
   * Sets the TCP_NODELAY option on the socket.
   *
   * @param on true to enable, false to disable
   *
   * @exception SocketException If an error occurs or Socket is not connected
   *
   * @since 1.1
   */
  public void setTcpNoDelay(boolean on) throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    getImpl().setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
  }

  /**
   * Tests whether or not the TCP_NODELAY option is set on the socket.
   * Returns true if enabled, false if disabled. When on it disables the
   * Nagle algorithm which means that packets are always send immediatly and
   * never merged together to reduce network trafic.
   *
   * @return Whether or not TCP_NODELAY is set
   *
   * @exception SocketException If an error occurs or Socket not connected
   *
   * @since 1.1
   */
  public boolean getTcpNoDelay() throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    Object on = getImpl().getOption(SocketOptions.TCP_NODELAY);

    if (on instanceof Boolean)
      return (((Boolean) on).booleanValue());
    else
      throw new SocketException("Internal Error");
  }

  /**
   * Sets the value of the SO_LINGER option on the socket.  If the
   * SO_LINGER option is set on a socket and there is still data waiting to
   * be sent when the socket is closed, then the close operation will block
   * until either that data is delivered or until the timeout period
   * expires.  The linger interval is specified in hundreths of a second
   * (platform specific?)
   *
   * @param on true to enable SO_LINGER, false to disable
   * @param linger The SO_LINGER timeout in hundreths of a second or -1 if
   * SO_LINGER not set.
   *
   * @exception SocketException If an error occurs or Socket not connected
   * @exception IllegalArgumentException If linger is negative
   *
   * @since 1.1
   */
  public void setSoLinger(boolean on, int linger) throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    if (on)
      {
	if (linger < 0)
	  throw new IllegalArgumentException("SO_LINGER must be >= 0");

	if (linger > 65535)
	  linger = 65535;

	getImpl().setOption(SocketOptions.SO_LINGER, new Integer(linger));
      }
    else
      getImpl().setOption(SocketOptions.SO_LINGER, Boolean.valueOf(false));
  }

  /**
   * Returns the value of the SO_LINGER option on the socket.  If the
   * SO_LINGER option is set on a socket and there is still data waiting to
   * be sent when the socket is closed, then the close operation will block
   * until either that data is delivered or until the timeout period
   * expires.  This method either returns the timeouts (in hundredths of
   * of a second (platform specific?)) if SO_LINGER is set, or -1 if
   * SO_LINGER is not set.
   *
   * @return The SO_LINGER timeout in hundreths of a second or -1
   * if SO_LINGER not set
   *
   * @exception SocketException If an error occurs or Socket is not connected
   *
   * @since 1.1
   */
  public int getSoLinger() throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    Object linger = getImpl().getOption(SocketOptions.SO_LINGER);

    if (linger instanceof Integer)
      return (((Integer) linger).intValue());
    else
      return -1;
  }

  /**
   * Sends urgent data through the socket
   *
   * @param data The data to send.
   * Only the lowest eight bits of data are sent
   *
   * @exception IOException If an error occurs
   *
   * @since 1.4
   */
  public void sendUrgentData(int data) throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    getImpl().sendUrgentData(data);
  }

  /**
   * Enables/disables the SO_OOBINLINE option
   *
   * @param on True if SO_OOBLINE should be enabled
   *
   * @exception SocketException If an error occurs
   *
   * @since 1.4
   */
  public void setOOBInline(boolean on) throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    getImpl().setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(on));
  }

  /**
   * Returns the current setting of the SO_OOBINLINE option for this socket
   *
   * @return True if SO_OOBINLINE is set, false otherwise.
   *
   * @exception SocketException If an error occurs
   *
   * @since 1.4
   */
  public boolean getOOBInline() throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    Object buf = getImpl().getOption(SocketOptions.SO_OOBINLINE);

    if (buf instanceof Boolean)
      return (((Boolean) buf).booleanValue());
    else
      throw new SocketException("Internal Error: Unexpected type");
  }

  /**
   * Sets the value of the SO_TIMEOUT option on the socket.  If this value
   * is set, and an read/write is performed that does not complete within
   * the timeout period, a short count is returned (or an EWOULDBLOCK signal
   * would be sent in Unix if no data had been read).  A value of 0 for
   * this option implies that there is no timeout (ie, operations will
   * block forever).  On systems that have separate read and write timeout
   * values, this method returns the read timeout.  This
   * value is in milliseconds.
   *
   * @param timeout The length of the timeout in milliseconds, or
   * 0 to indicate no timeout.
   *
   * @exception SocketException If an error occurs or Socket not connected
   *
   * @since 1.1
   */
  public synchronized void setSoTimeout(int timeout) throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    if (timeout < 0)
      throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0");

    getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
  }

  /**
   * Returns the value of the SO_TIMEOUT option on the socket.  If this value
   * is set, and an read/write is performed that does not complete within
   * the timeout period, a short count is returned (or an EWOULDBLOCK signal
   * would be sent in Unix if no data had been read).  A value of 0 for
   * this option implies that there is no timeout (ie, operations will
   * block forever).  On systems that have separate read and write timeout
   * values, this method returns the read timeout.  This
   * value is in thousandths of a second (implementation specific?).
   *
   * @return The length of the timeout in thousandth's of a second or 0
   * if not set
   *
   * @exception SocketException If an error occurs or Socket not connected
   *
   * @since 1.1
   */
  public synchronized int getSoTimeout() throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    Object timeout = getImpl().getOption(SocketOptions.SO_TIMEOUT);
    if (timeout instanceof Integer)
      return (((Integer) timeout).intValue());
    else
      return 0;
  }

  /**
   * This method sets the value for the system level socket option
   * SO_SNDBUF to the specified value.  Note that valid values for this
   * option are specific to a given operating system.
   *
   * @param size The new send buffer size.
   *
   * @exception SocketException If an error occurs or Socket not connected
   * @exception IllegalArgumentException If size is 0 or negative
   *
   * @since 1.2
   */
  public void setSendBufferSize(int size) throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    if (size <= 0)
      throw new IllegalArgumentException("SO_SNDBUF value must be > 0");

    getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
  }

  /**
   * This method returns the value of the system level socket option
   * SO_SNDBUF, which is used by the operating system to tune buffer
   * sizes for data transfers.
   *
   * @return The send buffer size.
   *
   * @exception SocketException If an error occurs or socket not connected
   *
   * @since 1.2
   */
  public int getSendBufferSize() throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    Object buf = getImpl().getOption(SocketOptions.SO_SNDBUF);

    if (buf instanceof Integer)
      return (((Integer) buf).intValue());
    else
      throw new SocketException("Internal Error: Unexpected type");
  }

  /**
   * This method sets the value for the system level socket option
   * SO_RCVBUF to the specified value.  Note that valid values for this
   * option are specific to a given operating system.
   *
   * @param size The new receive buffer size.
   *
   * @exception SocketException If an error occurs or Socket is not connected
   * @exception IllegalArgumentException If size is 0 or negative
   *
   * @since 1.2
   */
  public void setReceiveBufferSize(int size) throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    if (size <= 0)
      throw new IllegalArgumentException("SO_RCVBUF value must be > 0");

    getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
  }

  /**
   * This method returns the value of the system level socket option
   * SO_RCVBUF, which is used by the operating system to tune buffer
   * sizes for data transfers.
   *
   * @return The receive buffer size.
   *
   * @exception SocketException If an error occurs or Socket is not connected
   *
   * @since 1.2
   */
  public int getReceiveBufferSize() throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    Object buf = getImpl().getOption(SocketOptions.SO_RCVBUF);

    if (buf instanceof Integer)
      return (((Integer) buf).intValue());
    else
      throw new SocketException("Internal Error: Unexpected type");
  }

  /**
   * This method sets the value for the socket level socket option
   * SO_KEEPALIVE.
   *
   * @param on True if SO_KEEPALIVE should be enabled
   *
   * @exception SocketException If an error occurs or Socket is not connected
   *
   * @since 1.3
   */
  public void setKeepAlive(boolean on) throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    getImpl().setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(on));
  }

  /**
   * This method returns the value of the socket level socket option
   * SO_KEEPALIVE.
   *
   * @return The setting
   *
   * @exception SocketException If an error occurs or Socket is not connected
   *
   * @since 1.3
   */
  public boolean getKeepAlive() throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    Object buf = getImpl().getOption(SocketOptions.SO_KEEPALIVE);

    if (buf instanceof Boolean)
      return (((Boolean) buf).booleanValue());
    else
      throw new SocketException("Internal Error: Unexpected type");
  }

  /**
   * Closes the socket.
   *
   * @exception IOException If an error occurs
   */
  public synchronized void close() throws IOException
  {
    if (isClosed())
      return;

    getImpl().close();
    impl = null;
    bound = false;

    if (getChannel() != null)
      getChannel().close();
  }

  /**
   * Converts this <code>Socket</code> to a <code>String</code>.
   *
   * @return The <code>String</code> representation of this <code>Socket</code>
   */
  public String toString()
  {
    try
      {
	if (isConnected())
	  return ("Socket[addr=" + getImpl().getInetAddress() + ",port="
	         + getImpl().getPort() + ",localport="
	         + getImpl().getLocalPort() + "]");
      }
    catch (SocketException e)
      {
	// This cannot happen as we are connected.
      }

    return "Socket[unconnected]";
  }

  /**
   * Sets the <code>SocketImplFactory</code>.  This may be done only once per
   * virtual machine.  Subsequent attempts will generate a
   * <code>SocketException</code>.  Note that a <code>SecurityManager</code>
   * check is made prior to setting the factory.  If
   * insufficient privileges exist to set the factory, then an
   * <code>IOException</code> will be thrown.
   *
   * @param fac the factory to set
   *
   * @exception SecurityException If the <code>SecurityManager</code> does
   * not allow this operation.
   * @exception SocketException If the SocketImplFactory is already defined
   * @exception IOException If any other error occurs
   */
  public static synchronized void setSocketImplFactory(SocketImplFactory fac)
    throws IOException
  {
    // See if already set
    if (factory != null)
      throw new SocketException("SocketImplFactory already defined");

    // Check permissions
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkSetFactory();

    if (fac == null)
      throw new SocketException("SocketImplFactory cannot be null");

    factory = fac;
  }

  /**
   * Closes the input side of the socket stream.
   *
   * @exception IOException If an error occurs.
   *
   * @since 1.3
   */
  public void shutdownInput() throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    getImpl().shutdownInput();
    inputShutdown = true;
  }

  /**
   * Closes the output side of the socket stream.
   *
   * @exception IOException If an error occurs.
   *
   * @since 1.3
   */
  public void shutdownOutput() throws IOException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    getImpl().shutdownOutput();
    outputShutdown = true;
  }

  /**
   * Returns the socket channel associated with this socket.
   *
   * @return the associated socket channel,
   * null if no associated channel exists
   *
   * @since 1.4
   */
  public SocketChannel getChannel()
  {
    return null;
  }

  /**
   * Checks if the SO_REUSEADDR option is enabled
   *
   * @return True if SO_REUSEADDR is set, false otherwise.
   *
   * @exception SocketException If an error occurs
   *
   * @since 1.4
   */
  public boolean getReuseAddress() throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    Object reuseaddr = getImpl().getOption(SocketOptions.SO_REUSEADDR);

    if (! (reuseaddr instanceof Boolean))
      throw new SocketException("Internal Error");

    return ((Boolean) reuseaddr).booleanValue();
  }

  /**
   * Enables/Disables the SO_REUSEADDR option
   *
   * @param reuseAddress true if SO_REUSEADDR should be enabled,
   * false otherwise
   *
   * @exception SocketException If an error occurs
   *
   * @since 1.4
   */
  public void setReuseAddress(boolean reuseAddress) throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    getImpl().setOption(SocketOptions.SO_REUSEADDR,
                        Boolean.valueOf(reuseAddress));
  }

  /**
   * Returns the current traffic class
   *
   * @return The current traffic class.
   *
   * @exception SocketException If an error occurs
   *
   * @see Socket#setTrafficClass(int tc)
   *
   * @since 1.4
   */
  public int getTrafficClass() throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    Object obj = getImpl().getOption(SocketOptions.IP_TOS);

    if (obj instanceof Integer)
      return ((Integer) obj).intValue();
    else
      throw new SocketException("Unexpected type");
  }

  /**
   * Sets the traffic class value
   *
   * @param tc The traffic class
   *
   * @exception SocketException If an error occurs
   * @exception IllegalArgumentException If tc value is illegal
   *
   * @see Socket#getTrafficClass()
   *
   * @since 1.4
   */
  public void setTrafficClass(int tc) throws SocketException
  {
    if (isClosed())
      throw new SocketException("socket is closed");

    if (tc < 0 || tc > 255)
      throw new IllegalArgumentException();

    getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
  }

  /**
   * Checks if the socket is connected
   *
   * @return True if socket is connected, false otherwise.
   *
   * @since 1.4
   */
  public boolean isConnected()
  {
    try
      {
	if (getImpl() == null)
	  return false;

	return getImpl().getInetAddress() != null;
      }
    catch (SocketException e)
      {
	return false;
      }
  }

  /**
   * Checks if the socket is already bound.
   *
   * @return True if socket is bound, false otherwise.
   *
   * @since 1.4
   */
  public boolean isBound()
  {
    return bound;
  }

  /**
   * Checks if the socket is closed.
   *
   * @return True if socket is closed, false otherwise.
   *
   * @since 1.4
   */
  public boolean isClosed()
  {
    return impl == null;
  }

  /**
   * Checks if the socket's input stream is shutdown
   *
   * @return True if input is shut down.
   *
   * @since 1.4
   */
  public boolean isInputShutdown()
  {
    return inputShutdown;
  }

  /**
   * Checks if the socket's output stream is shutdown
   *
   * @return True if output is shut down.
   *
   * @since 1.4
   */
  public boolean isOutputShutdown()
  {
    return outputShutdown;
  }
}
