diff options
author | Mark Wielaard <mark@klomp.org> | 2002-01-12 10:11:13 +0000 |
---|---|---|
committer | Mark Wielaard <mark@gcc.gnu.org> | 2002-01-12 10:11:13 +0000 |
commit | 9566a90c6b3691f90c67a1db620f337842d35838 (patch) | |
tree | 91031c9de9f57606f82c06f6060a409dd4ed0d03 /libjava/java | |
parent | e37af218eed960ea5d499158db780aa4821e02cc (diff) | |
download | gcc-9566a90c6b3691f90c67a1db620f337842d35838.zip gcc-9566a90c6b3691f90c67a1db620f337842d35838.tar.gz gcc-9566a90c6b3691f90c67a1db620f337842d35838.tar.bz2 |
InetAddress.java (ANY_IF): moved from ServerSocket.
* java/net/InetAddress.java (ANY_IF): moved from ServerSocket.
* java/net/DatagramSocket.java (DatagramSocket): use ANY_IF from
InetAddress.
* java/net/MulticastSocket.java (MulticastSocket): Likewise.
* java/net/Socket.java: Merge with Classpath.
* java/net/ServerSocket.java: Likewise.
From-SVN: r48797
Diffstat (limited to 'libjava/java')
-rw-r--r-- | libjava/java/net/DatagramSocket.java | 6 | ||||
-rw-r--r-- | libjava/java/net/InetAddress.java | 4 | ||||
-rw-r--r-- | libjava/java/net/MulticastSocket.java | 4 | ||||
-rw-r--r-- | libjava/java/net/ServerSocket.java | 226 | ||||
-rw-r--r-- | libjava/java/net/Socket.java | 620 |
5 files changed, 707 insertions, 153 deletions
diff --git a/libjava/java/net/DatagramSocket.java b/libjava/java/net/DatagramSocket.java index 334e003..6e33e3b 100644 --- a/libjava/java/net/DatagramSocket.java +++ b/libjava/java/net/DatagramSocket.java @@ -28,12 +28,12 @@ public class DatagramSocket public DatagramSocket() throws SocketException { - this(0, ServerSocket.ANY_IF); + this(0, null); } public DatagramSocket(int port) throws SocketException { - this(port, ServerSocket.ANY_IF); + this(port, null); } public DatagramSocket(int port, InetAddress laddr) throws SocketException @@ -66,7 +66,7 @@ public class DatagramSocket if (this instanceof MulticastSocket) impl.setOption(SocketOptions.SO_REUSEADDR, new Boolean(true)); - impl.bind(port, laddr == null ? ServerSocket.ANY_IF : laddr); + impl.bind(port, laddr == null ? InetAddress.ANY_IF : laddr); } public void close() diff --git a/libjava/java/net/InetAddress.java b/libjava/java/net/InetAddress.java index f1a1235..49bc310 100644 --- a/libjava/java/net/InetAddress.java +++ b/libjava/java/net/InetAddress.java @@ -240,6 +240,10 @@ public final class InetAddress implements java.io.Serializable return lookup(host, null, true); } + static final byte[] zeros = {0,0,0,0}; + /* dummy InetAddress, used to bind socket to any (all) network interfaces */ + static final InetAddress ANY_IF = new InetAddress(zeros, null); + private static final byte[] localhostAddress = { 127, 0, 0, 1 }; private static native String getLocalHostname (); diff --git a/libjava/java/net/MulticastSocket.java b/libjava/java/net/MulticastSocket.java index a782cff..b0c0813 100644 --- a/libjava/java/net/MulticastSocket.java +++ b/libjava/java/net/MulticastSocket.java @@ -64,7 +64,7 @@ public class MulticastSocket extends DatagramSocket */ public MulticastSocket() throws IOException { - super(0, ServerSocket.ANY_IF); + super(0, null); } /** @@ -76,7 +76,7 @@ public class MulticastSocket extends DatagramSocket */ public MulticastSocket(int port) throws IOException { - super(port, ServerSocket.ANY_IF); + super(port, null); } /** diff --git a/libjava/java/net/ServerSocket.java b/libjava/java/net/ServerSocket.java index bc1b072..23792a9 100644 --- a/libjava/java/net/ServerSocket.java +++ b/libjava/java/net/ServerSocket.java @@ -1,111 +1,265 @@ -// ServerSocket.java +/* ServerSocket.java -- Class for implementing server side sockets + Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc. -/* Copyright (C) 1999 Free Software Foundation +This file is part of GNU Classpath. - This file is part of libgcj. +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. -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -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., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. -/** - * @author Per Bothner <bothner@cygnus.com> - * @date January 6, 1999. - */ - -/** Written using on-line Java Platform 1.2 API Specification. - * Status: I believe all methods are implemented. - */ +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ package java.net; -import java.io.*; +import java.io.IOException; + +/* Written using on-line Java Platform 1.2 API Specification. + * Status: I believe all methods are implemented. + */ + +/** + * This class models server side sockets. The basic model is that the + * server socket is created and bound to some well known port. It then + * listens for and accepts connections. At that point the client and + * server sockets are ready to communicate with one another utilizing + * whatever application layer protocol they desire. + * <p> + * As with the <code>Socket</code> class, most instance methods of this class + * simply redirect their calls to an implementation class. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + * @author Per Bothner (bothner@cygnus.com) + */ public class ServerSocket { - static SocketImplFactory factory; - SocketImpl impl; - static final byte[] zeros = {0,0,0,0}; - /* dummy InetAddress, used to bind socket to any (all) network interfaces */ - static final InetAddress ANY_IF = new InetAddress(zeros, null); + // Class Variables + + /** + * This is the user defined SocketImplFactory, if one is supplied + */ + private static SocketImplFactory factory; + // Instance Variables + + /** + * This is the SocketImp object to which most instance methods in this + * class are redirected + */ + private SocketImpl impl; + + /** + * Private constructor that simply sets the implementation. + */ + private ServerSocket() + { + if (factory != null) + impl = factory.createSocketImpl(); + else + impl = new PlainSocketImpl(); + } + + /** + * Creates a server socket and binds it to the specified port. If the + * port number is 0, a random free port will be chosen. The pending + * connection queue on this socket will be set to 50. + * + * @param port The port number to bind to + * + * @exception IOException If an error occurs + */ public ServerSocket (int port) throws java.io.IOException { this(port, 50); } + /** + * Creates a server socket and binds it to the specified port. If the + * port number is 0, a random free port will be chosen. The pending + * connection queue on this socket will be set to the value passed as + * arg2. + * + * @param port The port number to bind to + * @param backlog The length of the pending connection queue + * + * @exception IOException If an error occurs + */ public ServerSocket (int port, int backlog) throws java.io.IOException { - this(port, backlog, ANY_IF); + this(port, backlog, null); } + /** + * Creates a server socket and binds it to the specified port. If the + * port number is 0, a random free port will be chosen. The pending + * connection queue on this socket will be set to the value passed as + * backlog. The third argument specifies a particular local address to + * bind t or null to bind to all local address. + * + * @param port The port number to bind to + * @param backlog The length of the pending connection queue + * @param bindAddr The address to bind to, or null to bind to all addresses + * + * @exception IOException If an error occurs + */ public ServerSocket (int port, int backlog, InetAddress bindAddr) throws java.io.IOException { - if (factory == null) - this.impl = new PlainSocketImpl(); - else - this.impl = factory.createSocketImpl(); + this(); + if (impl == null) + throw new IOException("Cannot initialize Socket implementation"); + SecurityManager s = System.getSecurityManager(); if (s != null) s.checkListen(port); + + if (bindAddr == null) + bindAddr = InetAddress.ANY_IF; + impl.create(true); - impl.bind(bindAddr == null ? ANY_IF : bindAddr, port); + impl.bind(bindAddr, port); impl.listen(backlog); } + /** + * This method returns the local address to which this socket is bound + * + * @return The socket's local address + */ public InetAddress getInetAddress() { return impl.getInetAddress(); } + /** + * This method returns the local port number to which this socket is bound + * + * @return The socket's port number + */ public int getLocalPort() { return impl.getLocalPort(); } + /** + * Accepts a new connection and returns a connected <code>Socket</code> + * instance representing that connection. This method will block until a + * connection is available. + * + * @exception IOException If an error occurs + */ public Socket accept () throws IOException { - Socket s = new Socket(Socket.factory == null ? new PlainSocketImpl() - : Socket.factory.createSocketImpl()); + Socket s = new Socket(); implAccept (s); + return s; } + /** + * This protected method is used to help subclasses override + * <code>ServerSocket.accept()</code>. The passed in socket will be + * connected when this method returns. + * + * @param socket The socket that is used for the accepted connection + * + * @exception IOException If an error occurs + */ protected final void implAccept (Socket s) throws IOException { impl.accept(s.impl); } + /** + * Closes this socket and stops listening for connections + * + * @exception IOException If an error occurs + */ public void close () throws IOException { impl.close(); } - public synchronized void setSoTimeout (int timeout) throws SocketException + /** + * Sets the value of SO_TIMEOUT. A value of 0 implies that SO_TIMEOUT is + * disabled (ie, operations never time out). This is the number of + * milliseconds a socket operation can block before an + * InterruptedIOException is thrown. + * + * @param timeout The new SO_TIMEOUT value + * + * @exception IOException If an error occurs + */ + public void setSoTimeout (int timeout) throws SocketException { if (timeout < 0) - throw new IllegalArgumentException("Invalid timeout: " + timeout); + throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0"); impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout)); } - public synchronized int getSoTimeout () throws SocketException + /** + * Retrieves the current value of the SO_TIMEOUT setting. A value of 0 + * implies that SO_TIMEOUT is disabled (ie, operations never time out). + * This is the number of milliseconds a socket operation can block before + * an InterruptedIOException is thrown. + * + * @return The value of SO_TIMEOUT + * + * @exception IOException If an error occurs + */ + public int getSoTimeout () throws IOException { Object timeout = impl.getOption(SocketOptions.SO_TIMEOUT); - if (timeout instanceof Integer) - return ((Integer)timeout).intValue(); - else - return 0; + + if (!(timeout instanceof Integer)) + throw new IOException("Internal Error"); + + return ((Integer)timeout).intValue(); } + /** + * Returns the value of this socket as a <code>String</code>. + * + * @return This socket represented as a <code>String</code>. + */ public String toString () { - return "ServerSocket" + impl.toString(); + return "ServerSocket " + impl.toString(); } + // Class methods + + /** + * Sets the <code>SocketImplFactory</code> for all + * <code>ServerSocket</code>'s. This may only be done + * once per virtual machine. Subsequent attempts will generate an + * exception. Note that a <code>SecurityManager</code> check is made prior + * to setting the factory. If insufficient privileges exist to set the + * factory, an exception will be thrown + * + * @exception SecurityException If this operation is not allowed by the + * <code>SecurityManager</code>. + * @exception SocketException If the factory object is already defined + * @exception IOException If any other error occurs + */ public static synchronized void setSocketFactory (SocketImplFactory fac) throws IOException { diff --git a/libjava/java/net/Socket.java b/libjava/java/net/Socket.java index 34ea165..6bd6183 100644 --- a/libjava/java/net/Socket.java +++ b/libjava/java/net/Socket.java @@ -1,263 +1,659 @@ -// Socket.java +/* Socket.java -- Client socket implementation + Copyright (C) 1998, 1999, 2000, 2002 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., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -/* Copyright (C) 1999 Free Software Foundation +package java.net; - This file is part of libgcj. +import java.io.*; -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ +/* Written using on-line Java Platform 1.2 API Specification. + * Status: I believe all methods are implemented. + */ /** - * @author Per Bothner <bothner@cygnus.com> - * @date January 6, 1999. - */ - -/** Written using on-line Java Platform 1.2 API Specification. - * Status: I believe all methods are implemented. - */ - -package java.net; -import java.io.*; - + * 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 { + + // Class Variables + + /** + * This is the user SocketImplFactory for this class. If this variable is + * null, a default factory is used. + */ static SocketImplFactory factory; + + // Instance Variables + + /** + * The implementation object to which calls are redirected + */ SocketImpl impl; + // Constructors + + /** + * 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. + */ protected 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. This value can be <code>null</code>, but if it is, all instance + * methods in <code>Socket</code> should be overridden because most of them + * rely on this value being populated. + * + * @param impl The <code>SocketImpl</code> to use for this + * <code>Socket</code> + * + * @exception SocketException If an error occurs + */ protected Socket (SocketImpl impl) throws SocketException { 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 + */ public Socket (String host, int port) throws UnknownHostException, IOException { - this(factory == null ? new PlainSocketImpl() : factory.createSocketImpl()); - SecurityManager s = System.getSecurityManager(); - if (s != null) - s.checkConnect(host, port); - impl.create(true); - // 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. - impl.connect(host, port); + 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 + */ public Socket (InetAddress address, int port) throws IOException { - this(factory == null ? new PlainSocketImpl() : factory.createSocketImpl()); - SecurityManager s = System.getSecurityManager(); - if (s != null) - s.checkConnect(address.getHostName(), port); - impl.create(true); - // 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. - impl.connect(address, port); + 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 loadAddr 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. + */ public Socket (String host, int port, InetAddress localAddr, int localPort) throws IOException { - this(factory == null ? new PlainSocketImpl() : factory.createSocketImpl()); - SecurityManager s = System.getSecurityManager(); - if (s != null) - s.checkConnect(host, port); - impl.create(true); - // FIXME: JCL p. 1587 says if localAddr is null, use getLocalAddress(). - impl.bind(localAddr, localPort); - impl.connect(host, port); + 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 + */ public Socket (InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException { - this(factory == null ? new PlainSocketImpl() : factory.createSocketImpl()); - SecurityManager s = System.getSecurityManager(); - if (s != null) - s.checkConnect(address.getHostName(), port); - impl.create(true); - // FIXME: JCL p. 1587 says if localAddr is null, use getLocalAddress(). - impl.bind(localAddr, localPort); - impl.connect(address, port); + this(address, port, localAddr, localPort, true); } /** - * @deprecated Use DatagramSocket instead for UDP transport. + * 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 + * + * @deprecated Use the <code>DatagramSocket</code> class to create + * datagram oriented sockets. */ public Socket (String host, int port, boolean stream) throws IOException { - impl = factory == null ? new PlainSocketImpl() - : factory.createSocketImpl(); - impl.create(stream); - SecurityManager s = System.getSecurityManager(); - if (s != null) - s.checkConnect(host, port); - // 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. - impl.connect(host, port); + this(InetAddress.getByName(host), port, null, 0, stream); } /** - * @deprecated Use DatagramSocket instead for UDP transport. + * 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 + * + * @deprecated Use the <code>DatagramSocket</code> class to create + * datagram oriented sockets. */ public Socket (InetAddress host, int port, boolean stream) throws IOException { - impl = factory == null ? new PlainSocketImpl() - : factory.createSocketImpl(); + 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 + */ + private Socket(InetAddress raddr, int rport, InetAddress laddr, int lport, + boolean stream) throws IOException + { + this(); + if (impl == null) + throw new IOException("Cannot initialize Socket implementation"); + + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkConnect(raddr.getHostName(), rport); + impl.create(stream); - SecurityManager s = System.getSecurityManager(); - if (s != null) - s.checkConnect(host.getHostName(), port); + // 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. - impl.connect(host, port); + if (laddr != null) + impl.bind(laddr, lport); + + if (raddr != null) + impl.connect(raddr, rport); } + /** + * 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 () { - return impl.getInetAddress(); + if (impl != null) + return impl.getInetAddress(); + + return null; } + /** + * Returns the local address to which this socket is bound. If this socket + * is not connected, then <code>null</code> is returned. + * + * @return The local address + */ public InetAddress getLocalAddress () { - // FIXME: see note in DatagramSocket.java about checkConnect() and security + if (impl == null) + return null; + + InetAddress addr = null; try { - return (InetAddress)impl.getOption(SocketOptions.SO_BINDADDR); + addr = (InetAddress)impl.getOption(SocketOptions.SO_BINDADDR); } - catch (SocketException x) + catch(SocketException e) { - // (hopefully) shouldn't happen - System.err.println(x); - throw new java.lang.InternalError("Error in PlainSocketImpl.getOption"); + // (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 -1 is returned. + * + * @return The remote port this socket is connected to + */ public int getPort () { - return impl.getPort(); + if (impl != null) + return impl.getPort(); + + return -1; } + /** + * 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 () { - return impl.getLocalPort(); + if (impl != null) + return impl.getLocalPort(); + + return -1; } + /** + * 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 { - return impl.getInputStream(); + if (impl != null) + return(impl.getInputStream()); + + throw new IOException("Not connected"); } + /** + * 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 { - return impl.getOutputStream(); + if (impl != null) + return impl.getOutputStream(); + + throw new IOException("Not connected"); } + /** + * 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 + */ public void setTcpNoDelay (boolean on) throws SocketException { - impl.setOption( SocketOptions.TCP_NODELAY, new Boolean(on) ); + if (impl == null) + throw new SocketException("Not connected"); + + impl.setOption(SocketOptions.TCP_NODELAY, new Boolean(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 + */ public boolean getTcpNoDelay() throws SocketException { - Boolean bool = (Boolean)impl.getOption( SocketOptions.TCP_NODELAY ); - return bool.booleanValue(); + if (impl == null) + throw new SocketException("Not connected"); + + Object on = impl.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 + */ public void setSoLinger(boolean on, int linger) throws SocketException { - if ( on && (linger >= 0) ) + if (impl == null) + throw new SocketException("No socket created"); + + if (on == true) { - if (linger > 65535) - linger = 65535; - impl.setOption( SocketOptions.SO_LINGER, new Integer(linger) ); - } - else if ( on && (linger < 0) ) - throw new IllegalArgumentException("SO_LINGER must be >= 0"); + if (linger < 0) + throw new IllegalArgumentException("SO_LINGER must be >= 0"); + + if (linger > 65535) + linger = 65535; + + impl.setOption(SocketOptions.SO_LINGER, new Integer(linger)); + } else - impl.setOption( SocketOptions.SO_LINGER, new Boolean(false) ); + { + impl.setOption(SocketOptions.SO_LINGER, new Boolean(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 + */ public int getSoLinger() throws SocketException { - Object linger = impl.getOption(SocketOptions.SO_LINGER); - if (linger instanceof Integer) - return ((Integer)linger).intValue(); + if (impl == null) + throw new SocketException("Not connected"); + + Object linger = impl.getOption(SocketOptions.SO_LINGER); + if (linger instanceof Integer) + return(((Integer)linger).intValue()); else return -1; } + /** + * 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 thousandths of a second (****????*****) + * + * @param timeout 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 + */ public synchronized void setSoTimeout (int timeout) throws SocketException { + if (impl == null) + throw new SocketException("Not connected"); + if (timeout < 0) - throw new IllegalArgumentException("Invalid timeout: " + timeout); - + throw new IllegalArgumentException("SO_TIMEOUT value must be >= 0"); + impl.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 + */ public synchronized int getSoTimeout () throws SocketException { + if (impl == null) + throw new SocketException("Not connected"); + Object timeout = impl.getOption(SocketOptions.SO_TIMEOUT); - if (timeout instanceof Integer) - return ((Integer)timeout).intValue(); + if (timeout instanceof Integer) + return(((Integer)timeout).intValue()); else return 0; } - // JDK1.2 + /** + * 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 + * + * @since Java 1.2 + */ public void setSendBufferSize (int size) throws SocketException { + if (impl == null) + throw new SocketException("Not connected"); + if (size <= 0) - throw new IllegalArgumentException("Invalid buffer size: " + size); - + throw new IllegalArgumentException("SO_SNDBUF value must be > 0"); + impl.setOption(SocketOptions.SO_SNDBUF, new Integer(size)); } - // JDK1.2 + /** + * 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 Java 1.2 + */ public int getSendBufferSize () throws SocketException { - Integer buf = (Integer)impl.getOption(SocketOptions.SO_SNDBUF); - return buf.intValue(); + if (impl == null) + throw new SocketException("Not connected"); + + Object buf = impl.getOption(SocketOptions.SO_SNDBUF); + + if (buf instanceof Integer) + return(((Integer)buf).intValue()); + else + throw new SocketException("Internal Error: Unexpected type"); } - // JDK1.2 + /** + * 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 + * + * @since Java 1.2 + */ public void setReceiveBufferSize (int size) throws SocketException { - if (size <= 0) - throw new IllegalArgumentException("Invalid buffer size: " + size); + if (impl == null) + throw new SocketException("Not connected"); + if (size <= 0) + throw new IllegalArgumentException("SO_RCVBUF value must be > 0"); + impl.setOption(SocketOptions.SO_RCVBUF, new Integer(size)); } - // JDK1.2 + /** + * 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 Java 1.2 + */ public int getReceiveBufferSize () throws SocketException { - Integer buf = (Integer)impl.getOption(SocketOptions.SO_RCVBUF); - return buf.intValue(); + if (impl == null) + throw new SocketException("Not connected"); + + Object buf = impl.getOption(SocketOptions.SO_RCVBUF); + + if (buf instanceof Integer) + return(((Integer)buf).intValue()); + else + throw new SocketException("Internal Error: Unexpected type"); } + /** + * Closes the socket. + * + * @exception IOException If an error occurs + */ public synchronized void close () throws IOException { - impl.close(); + if (impl != null) + impl.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 () { - return "Socket" + impl.toString(); + return("Socket " + impl); } + // Class Methods + + /** + * 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. + * + * @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(); + factory = fac; } } |