home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1998 July & August
/
Pcwk78a98.iso
/
Internet
/
Javadraw
/
DATA.Z
/
Socket.java
< prev
next >
Wrap
Text File
|
1997-08-30
|
15KB
|
439 lines
/*
* @(#)Socket.java 1.29 97/02/10
*
* Copyright (c) 1995, 1996 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
* CopyrightVersion 1.1_beta
*
*/
package java.net;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
/**
* This class implements client sockets (also called just
* "sockets"). A socket is an endpoint for communication
* between two machines.
* <p>
* The actual work of the socket is performed by an instance of the
* <code>SocketImpl</code> class. An application, by changing
* the socket factory that creates the socket implementation,
* can configure itself to create sockets appropriate to the local
* firewall.
*
* @author unascribed
* @version 1.29, 02/10/97
* @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
* @see java.net.SocketImpl
* @since JDK1.0
*/
public
class Socket {
/**
* The implementation of this Socket.
*/
SocketImpl impl;
/**
* Creates an unconnected socket, with the
* system-default type of SocketImpl.
*
* @since JDK1.1
*/
protected Socket() {
impl = (factory != null) ? factory.createSocketImpl() :
new PlainSocketImpl();
}
/**
* Creates an unconnected Socket with a user-specified
* SocketImpl.
* <P>
* The <i>impl</i> parameter is an instance of a <B>SocketImpl</B>
* the subclass wishes to use on the Socket.
*
* @since JDK1.1
*/
protected Socket(SocketImpl impl) throws SocketException {
this.impl = impl;
}
/**
* Creates a stream socket and connects it to the specified port
* number on the named host.
* <p>
* If the application has specified a server socket factory, that
* factory's <code>createSocketImpl</code> method is called to create
* the actual socket implementation. Otherwise a "plain" socket is created.
*
* @param host the host name.
* @param port the port number.
* @exception IOException if an I/O error occurs when creating the socket.
* @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
* @see java.net.SocketImpl
* @see java.net.SocketImplFactory#createSocketImpl()
* @since JDK1.0
*/
public Socket(String host, int port)
throws UnknownHostException, IOException
{
this(InetAddress.getByName(host), port, null, 0, true);
}
/**
* Creates a stream socket and connects it to the specified port
* number at the specified IP address.
* <p>
* If the application has specified a socket factory, that factory's
* <code>createSocketImpl</code> method is called to create the
* actual socket implementation. Otherwise a "plain" socket is created.
*
* @param address the IP address.
* @param port the port number.
* @exception IOException if an I/O error occurs when creating the socket.
* @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
* @see java.net.SocketImpl
* @see java.net.SocketImplFactory#createSocketImpl()
* @since JDK1.0
*/
public Socket(InetAddress address, int port) throws IOException {
this(address, port, null, 0, true);
}
/**
* Creates a socket and connects it to the specified remote host on
* the specified remote port. The Socket will also bind() to the local
* address and port supplied.
* @param host the name of the remote host
* @param port the remote port
* @param localAddr the local address the socket is bound to
* @param localPort the local port the socket is bound to
* @since JDK1.1
*/
public Socket(String host, int port, InetAddress localAddr,
int localPort) throws IOException {
this(InetAddress.getByName(host), port, localAddr, localPort, true);
}
/**
* Creates a socket and connects it to the specified remote address on
* the specified remote port. The Socket will also bind() to the local
* address and port supplied.
* @param address the remote address
* @param port the remote port
* @param localAddr the local address the socket is bound to
* @param localPort the local port the socket is bound to
* @since JDK1.1
*/
public Socket(InetAddress address, int port, InetAddress localAddr,
int localPort) throws IOException {
this(address, port, localAddr, localPort, true);
};
/**
* Creates a stream socket and connects it to the specified port
* number on the named host.
* <p>
* If the stream argument is <code>true</code>, this creates a
* stream socket. If the stream argument is <code>false</code>, it
* creates a datagram socket.
* <p>
* If the application has specified a server socket factory, that
* factory's <code>createSocketImpl</code> method is called to create
* the actual socket implementation. Otherwise a "plain" socket is created.
*
* @param host the host name.
* @param port the port number.
* @param stream a <code>boolean</code> indicating whether this is
* a stream socket or a datagram socket.
* @exception IOException if an I/O error occurs when creating the socket.
* @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
* @see java.net.SocketImpl
* @see java.net.SocketImplFactory#createSocketImpl()
* @since JDK1.0
* @deprecated Use DatagramSocket instead for UDP transport.
*/
public Socket(String host, int port, boolean stream) throws IOException {
this(InetAddress.getByName(host), port, null, 0, stream);
}
/**
* Creates a socket and connects it to the specified port number at
* the specified IP address.
* <p>
* If the stream argument is <code>true</code>, this creates a
* stream socket. If the stream argument is <code>false</code>, it
* creates a datagram socket.
* <p>
* If the application has specified a server socket factory, that
* factory's <code>createSocketImpl</code> method is called to create
* the actual socket implementation. Otherwise a "plain" socket is created.
*
* @param address the IP address.
* @param port the port number.
* @param stream if <code>true</code>, create a stream socket;
* otherwise, create a datagram socket.
* @exception IOException if an I/O error occurs when creating the socket.
* @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
* @see java.net.SocketImpl
* @see java.net.SocketImplFactory#createSocketImpl()
* @since JDK1.0
* @deprecated Use DatagramSocket instead for UDP transport.
*/
public Socket(InetAddress host, int port, boolean stream) throws IOException {
this(host, port, null, 0, stream);
}
private Socket(InetAddress address, int port, InetAddress localAddr,
int localPort, boolean stream) throws IOException {
this();
if (port < 0 || port > 0xFFFF) {
throw new IllegalArgumentException("port out range:"+port);
}
if (localPort < 0 || localPort > 0xFFFF) {
throw new IllegalArgumentException("port out range:"+localPort);
}
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkConnect(address.getHostAddress(), port);
}
try {
impl.create(stream);
if (localAddr != null || localPort > 0) {
if (localAddr == null) {
localAddr = InetAddress.anyLocalAddress;
}
impl.bind(localAddr, localPort);
}
impl.connect(address, port);
} catch (SocketException e) {
impl.close();
throw e;
}
}
/**
* Returns the address to which the socket is connected.
*
* @return the remote IP address to which this socket is connected.
* @since JDK1.0
*/
public InetAddress getInetAddress() {
return impl.getInetAddress();
}
/**
* Gets the local address to which the socket is bound.
*
* @since JDK1.1
*/
public InetAddress getLocalAddress() {
InetAddress in = null;
try {
in = (InetAddress) impl.getOption(SocketOptions.SO_BINDADDR);
} catch (Exception e) {
in = InetAddress.anyLocalAddress; // "0.0.0.0"
}
return in;
}
/**
* Returns the remote port to which this socket is connected.
*
* @return the remote port number to which this socket is connected.
* @since JDK1.0
*/
public int getPort() {
return impl.getPort();
}
/**
* Returns the local port to which this socket is bound.
*
* @return the local port number to which this socket is connected.
* @since JDK1.0
*/
public int getLocalPort() {
return impl.getLocalPort();
}
/**
* Returns an input stream for this socket.
*
* @return an input stream for reading bytes from this socket.
* @exception IOException if an I/O error occurs when creating the
* input stream.
* @since JDK1.0
*/
public InputStream getInputStream() throws IOException {
return impl.getInputStream();
}
/**
* Returns an output stream for this socket.
*
* @return an output stream for writing bytes to this socket.
* @exception IOException if an I/O error occurs when creating the
* output stream.
* @since JDK1.0
*/
public OutputStream getOutputStream() throws IOException {
return impl.getOutputStream();
}
/**
* Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
*
* @since JDK1.1
*/
public void setTcpNoDelay(boolean on) throws SocketException {
impl.setOption(SocketOptions.TCP_NODELAY, new Boolean(on));
}
/**
* Tests if TCP_NODELAY is enabled.
*
* @since JDK1.1
*/
public boolean getTcpNoDelay() throws SocketException {
return ((Boolean) impl.getOption(SocketOptions.TCP_NODELAY)).booleanValue();
}
/**
* Enable/disable SO_LINGER with the specified linger time.
*
* @since JDK1.1
*/
public void setSoLinger(boolean on, int val) throws SocketException {
if (!on) {
impl.setOption(SocketOptions.SO_LINGER, new Boolean(on));
} else {
impl.setOption(SocketOptions.SO_LINGER, new Integer(val));
}
}
/**
* Returns setting for SO_LINGER. -1 returns implies that the
* option is disabled.
*
* @since JDK1.1
*/
public int getSoLinger() throws SocketException {
Object o = impl.getOption(SocketOptions.SO_LINGER);
if (o instanceof Integer) {
return ((Integer) o).intValue();
} else {
return -1;
}
}
/**
* Enable/disable SO_TIMEOUT with the specified timeout, in
* milliseconds. With this option set to a non-zero timeout,
* a read() call on the InputStream associated with this Socket
* will block for only this amount of time. If the timeout expires,
* a <B>java.io.InterruptedIOException</B> is raised, though the
* Socket is still valid. The option <B>must</B> be enabled
* prior to entering the blocking operation to have effect. The
* timeout must be > 0.
* A timeout of zero is interpreted as an infinite timeout.
*
* @since JDK 1.1
*/
public synchronized void setSoTimeout(int timeout) throws SocketException {
impl.setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
}
/**
* Returns setting for SO_TIMEOUT. 0 returns implies that the
* option is disabled (i.e., timeout of infinity).
*
* @since JDK1.1
*/
public synchronized int getSoTimeout() throws SocketException {
Object o = impl.getOption(SocketOptions.SO_TIMEOUT);
/* extra type safety */
if (o instanceof Integer) {
return ((Integer) o).intValue();
} else {
return 0;
}
}
/**
* Closes this socket.
*
* @exception IOException if an I/O error occurs when closing this socket.
* @since JDK1.0
*/
public synchronized void close() throws IOException {
impl.close();
}
/**
* Converts this socket to a <code>String</code>.
*
* @return a string representation of this socket.
* @since JDK1.0
*/
public String toString() {
return "Socket[addr=" + impl.getInetAddress() +
",port=" + impl.getPort() +
",localport=" + impl.getLocalPort() + "]";
}
/**
* The factory for all client sockets.
*/
private static SocketImplFactory factory;
/**
* Sets the client socket implementation factory for the
* application. The factory can be specified only once.
* <p>
* When an application creates a new client socket, the socket
* implementation factory's <code>createSocketImpl</code> method is
* called to create the actual socket implementation.
*
* @param fac the desired factory.
* @exception IOException if an I/O error occurs when setting the
* socket factory.
* @exception SocketException if the factory is already defined.
* @see java.net.SocketImplFactory#createSocketImpl()
* @since JDK1.0
*/
public static synchronized void setSocketImplFactory(SocketImplFactory fac)
throws IOException
{
if (factory != null) {
throw new SocketException("factory already defined");
}
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkSetFactory();
}
factory = fac;
}
}