0001: /*
0002: * @(#)Socket.java 1.63 06/10/10
0003: *
0004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006: *
0007: * This program is free software; you can redistribute it and/or
0008: * modify it under the terms of the GNU General Public License version
0009: * 2 only, as published by the Free Software Foundation.
0010: *
0011: * This program is distributed in the hope that it will be useful, but
0012: * WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * General Public License version 2 for more details (a copy is
0015: * included at /legal/license.txt).
0016: *
0017: * You should have received a copy of the GNU General Public License
0018: * version 2 along with this work; if not, write to the Free Software
0019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020: * 02110-1301 USA
0021: *
0022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023: * Clara, CA 95054 or visit www.sun.com if you need additional
0024: * information or have any questions.
0025: *
0026: */
0027:
0028: package java.net;
0029:
0030: import java.io.InputStream;
0031: import java.io.OutputStream;
0032: import java.io.IOException;
0033: import java.io.InterruptedIOException;
0034: import java.security.AccessController;
0035: import java.security.PrivilegedExceptionAction;
0036:
0037: /**
0038: * This class implements client sockets (also called just
0039: * "sockets"). A socket is an endpoint for communication
0040: * between two machines.
0041: * <p>
0042: * The actual work of the socket is performed by an instance of the
0043: * <code>SocketImpl</code> class. An application, by changing
0044: * the socket factory that creates the socket implementation,
0045: * can configure itself to create sockets appropriate to the local
0046: * firewall.
0047: *
0048: * @author unascribed
0049: * @version 1.56, 08/09/01
0050: * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
0051: * @see java.net.SocketImpl
0052: * @since JDK1.0
0053: */
0054: public class Socket {
0055: /**
0056: * Various states of this socket.
0057: */
0058: private boolean created = false;
0059: private boolean bound = false;
0060: private boolean connected = false;
0061: private boolean closed = false;
0062: private Object closeLock = new Object();
0063: private boolean shutIn = false;
0064: private boolean shutOut = false;
0065:
0066: /**
0067: * The implementation of this Socket.
0068: */
0069: SocketImpl impl;
0070:
0071: /**
0072: * Are we using an older SocketImpl?
0073: */
0074: private boolean oldImpl = false;
0075:
0076: /**
0077: * Creates an unconnected socket, with the
0078: * system-default type of SocketImpl.
0079: *
0080: * @since JDK1.1
0081: * @revised 1.4
0082: */
0083: public Socket() {
0084: setImpl();
0085: }
0086:
0087: /**
0088: * Creates an unconnected Socket with a user-specified
0089: * SocketImpl.
0090: * <P>
0091: * @param impl an instance of a <B>SocketImpl</B>
0092: * the subclass wishes to use on the Socket.
0093: *
0094: * @exception SocketException if there is an error in the underlying protocol,
0095: * such as a TCP error.
0096: * @since JDK1.1
0097: */
0098: protected Socket(SocketImpl impl) throws SocketException {
0099: this .impl = impl;
0100: if (impl != null) {
0101: checkOldImpl();
0102: this .impl.setSocket(this );
0103: }
0104: }
0105:
0106: /**
0107: * Creates a stream socket and connects it to the specified port
0108: * number on the named host.
0109: * <p>
0110: * If the specified host is <tt>null</tt> it is the equivalent of
0111: * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
0112: * In other words, it is equivalent to specifying an address of the
0113: * loopback interface. </p>
0114: * <p>
0115: * If the application has specified a server socket factory, that
0116: * factory's <code>createSocketImpl</code> method is called to create
0117: * the actual socket implementation. Otherwise a "plain" socket is created.
0118: * <p>
0119: * If there is a security manager, its
0120: * <code>checkConnect</code> method is called
0121: * with the host address and <code>port</code>
0122: * as its arguments. This could result in a SecurityException.
0123: *
0124: * @param host the host name, or <code>null</code> for the loopback address.
0125: * @param port the port number.
0126: *
0127: * @exception UnknownHostException if the IP address of
0128: * the host could not be determined.
0129: *
0130: * @exception IOException if an I/O error occurs when creating the socket.
0131: * @exception SecurityException if a security manager exists and its
0132: * <code>checkConnect</code> method doesn't allow the operation.
0133: * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
0134: * @see java.net.SocketImpl
0135: * @see java.net.SocketImplFactory#createSocketImpl()
0136: * @see SecurityManager#checkConnect
0137: */
0138: public Socket(String host, int port) throws UnknownHostException,
0139: IOException {
0140: this (host != null ? new InetSocketAddress(host, port)
0141: : new InetSocketAddress(InetAddress.getByName(null),
0142: port), new InetSocketAddress(0), true);
0143: }
0144:
0145: /**
0146: * Creates a stream socket and connects it to the specified port
0147: * number at the specified IP address.
0148: * <p>
0149: * If the application has specified a socket factory, that factory's
0150: * <code>createSocketImpl</code> method is called to create the
0151: * actual socket implementation. Otherwise a "plain" socket is created.
0152: * <p>
0153: * If there is a security manager, its
0154: * <code>checkConnect</code> method is called
0155: * with the host address and <code>port</code>
0156: * as its arguments. This could result in a SecurityException.
0157: *
0158: * @param address the IP address.
0159: * @param port the port number.
0160: * @exception IOException if an I/O error occurs when creating the socket.
0161: * @exception SecurityException if a security manager exists and its
0162: * <code>checkConnect</code> method doesn't allow the operation.
0163: * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
0164: * @see java.net.SocketImpl
0165: * @see java.net.SocketImplFactory#createSocketImpl()
0166: * @see SecurityManager#checkConnect
0167: */
0168: public Socket(InetAddress address, int port) throws IOException {
0169: this (address != null ? new InetSocketAddress(address, port)
0170: : null, new InetSocketAddress(0), true);
0171: }
0172:
0173: /**
0174: * Creates a socket and connects it to the specified remote host on
0175: * the specified remote port. The Socket will also bind() to the local
0176: * address and port supplied.
0177: * <p>
0178: * If the specified host is <tt>null</tt> it is the equivalent of
0179: * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
0180: * In other words, it is equivalent to specifying an address of the
0181: * loopback interface. </p>
0182: * <p>
0183: * If there is a security manager, its
0184: * <code>checkConnect</code> method is called
0185: * with the host address and <code>port</code>
0186: * as its arguments. This could result in a SecurityException.
0187: *
0188: * @param host the name of the remote host, or <code>null</code> for the loopback address.
0189: * @param port the remote port
0190: * @param localAddr the local address the socket is bound to
0191: * @param localPort the local port the socket is bound to
0192: * @exception IOException if an I/O error occurs when creating the socket.
0193: * @exception SecurityException if a security manager exists and its
0194: * <code>checkConnect</code> method doesn't allow the operation.
0195: * @see SecurityManager#checkConnect
0196: * @since JDK1.1
0197: */
0198: public Socket(String host, int port, InetAddress localAddr,
0199: int localPort) throws IOException {
0200: this (host != null ? new InetSocketAddress(host, port)
0201: : new InetSocketAddress(InetAddress.getByName(null),
0202: port), new InetSocketAddress(localAddr,
0203: localPort), true);
0204: }
0205:
0206: /**
0207: * Creates a socket and connects it to the specified remote address on
0208: * the specified remote port. The Socket will also bind() to the local
0209: * address and port supplied.
0210: * <p>
0211: * If there is a security manager, its
0212: * <code>checkConnect</code> method is called
0213: * with the host address and <code>port</code>
0214: * as its arguments. This could result in a SecurityException.
0215: *
0216: * @param address the remote address
0217: * @param port the remote port
0218: * @param localAddr the local address the socket is bound to
0219: * @param localPort the local port the socket is bound to
0220: * @exception IOException if an I/O error occurs when creating the socket.
0221: * @exception SecurityException if a security manager exists and its
0222: * <code>checkConnect</code> method doesn't allow the operation.
0223: * @see SecurityManager#checkConnect
0224: * @since JDK1.1
0225: */
0226: public Socket(InetAddress address, int port, InetAddress localAddr,
0227: int localPort) throws IOException {
0228: this (address != null ? new InetSocketAddress(address, port)
0229: : null, new InetSocketAddress(localAddr, localPort),
0230: true);
0231: }
0232:
0233: /**
0234: * Creates a stream socket and connects it to the specified port
0235: * number on the named host.
0236: * <p>
0237: * If the specified host is <tt>null</tt> it is the equivalent of
0238: * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
0239: * In other words, it is equivalent to specifying an address of the
0240: * loopback interface. </p>
0241: * <p>
0242: * If the stream argument is <code>true</code>, this creates a
0243: * stream socket. If the stream argument is <code>false</code>, it
0244: * creates a datagram socket.
0245: * <p>
0246: * If the application has specified a server socket factory, that
0247: * factory's <code>createSocketImpl</code> method is called to create
0248: * the actual socket implementation. Otherwise a "plain" socket is created.
0249: * <p>
0250: * If there is a security manager, its
0251: * <code>checkConnect</code> method is called
0252: * with the host address and <code>port</code>
0253: * as its arguments. This could result in a SecurityException.
0254: * <p>
0255: * If a UDP socket is used, TCP/IP related socket options will not apply.
0256: *
0257: * param host the host name.
0258: * param port the port number.
0259: * param stream a <code>boolean</code> indicating whether this is
0260: * a stream socket or a datagram socket.
0261: * exception IOException if an I/O error occurs when creating the socket.
0262: * exception SecurityException if a security manager exists and its
0263: * <code>checkConnect</code> method doesn't allow the operation.
0264: * see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
0265: * see java.net.SocketImpl
0266: * see java.net.SocketImplFactory#createSocketImpl()
0267: * see SecurityManager#checkConnect
0268: * deprecated Use DatagramSocket instead for UDP transport.
0269: *
0270: public Socket(String host, int port, boolean stream) throws IOException {
0271: this(host != null ? new InetSocketAddress(host, port) :
0272: new InetSocketAddress(InetAddress.getByName(null), port),
0273: new InetSocketAddress(0), stream);
0274: }
0275: */
0276:
0277: /**
0278: * Creates a socket and connects it to the specified port number at
0279: * the specified IP address.
0280: * <p>
0281: * If the stream argument is <code>true</code>, this creates a
0282: * stream socket. If the stream argument is <code>false</code>, it
0283: * creates a datagram socket.
0284: * <p>
0285: * If the application has specified a server socket factory, that
0286: * factory's <code>createSocketImpl</code> method is called to create
0287: * the actual socket implementation. Otherwise a "plain" socket is created.
0288: *
0289: * <p>If there is a security manager, its
0290: * <code>checkConnect</code> method is called
0291: * with <code>host.getHostAddress()</code> and <code>port</code>
0292: * as its arguments. This could result in a SecurityException.
0293: * <p>
0294: * If UDP socket is used, TCP/IP related socket options will not apply.
0295: *
0296: * param host the IP address.
0297: * param port the port number.
0298: * param stream if <code>true</code>, create a stream socket;
0299: * otherwise, create a datagram socket.
0300: * exception IOException if an I/O error occurs when creating the socket.
0301: * exception SecurityException if a security manager exists and its
0302: * <code>checkConnect</code> method doesn't allow the operation.
0303: * see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
0304: * see java.net.SocketImpl
0305: * see java.net.SocketImplFactory#createSocketImpl()
0306: * see SecurityManager#checkConnect
0307: * deprecated Use DatagramSocket instead for UDP transport.
0308: *
0309: public Socket(InetAddress host, int port, boolean stream) throws IOException {
0310: this(host != null ? new InetSocketAddress(host, port) : null,
0311: new InetSocketAddress(0), stream);
0312: }
0313: */
0314:
0315: private Socket(SocketAddress address, SocketAddress localAddr,
0316: boolean stream) throws IOException {
0317: setImpl();
0318:
0319: // backward compatibility
0320: if (address == null)
0321: throw new NullPointerException();
0322:
0323: try {
0324: createImpl(stream);
0325: if (localAddr == null)
0326: localAddr = new InetSocketAddress(0);
0327: bind(localAddr);
0328: if (address != null)
0329: connect(address);
0330: } catch (SocketException e) {
0331: close();
0332: throw e;
0333: }
0334: }
0335:
0336: /**
0337: * Creates the socket implementation.
0338: *
0339: * @param stream a <code>boolean</code> value : <code>true</code> for a TCP socket,
0340: * <code>false</code> for UDP.
0341: * @throws IOException if creation fails
0342: * @since 1.4
0343: */
0344: void createImpl(boolean stream) throws SocketException {
0345: if (impl == null)
0346: setImpl();
0347: try {
0348: impl.create(stream);
0349: created = true;
0350: } catch (IOException e) {
0351: throw new SocketException(e.getMessage());
0352: }
0353: }
0354:
0355: private void checkOldImpl() {
0356: if (impl == null)
0357: return;
0358: // SocketImpl.connect() is a protected method, therefore we need to use
0359: // getDeclaredMethod, therefore we need permission to access the member
0360: try {
0361: AccessController
0362: .doPrivileged(new PrivilegedExceptionAction() {
0363: public Object run()
0364: throws NoSuchMethodException {
0365: Class[] cl = new Class[2];
0366: cl[0] = SocketAddress.class;
0367: cl[1] = Integer.TYPE;
0368: impl.getClass().getDeclaredMethod(
0369: "connect", cl);
0370: return null;
0371: }
0372: });
0373: } catch (java.security.PrivilegedActionException e) {
0374: oldImpl = true;
0375: }
0376: }
0377:
0378: /**
0379: * Sets impl to the system-default type of SocketImpl.
0380: * @since 1.4
0381: */
0382: void setImpl() {
0383: checkSocks();
0384: if (factory != null) {
0385: impl = factory.createSocketImpl();
0386: checkOldImpl();
0387: } else {
0388: // No need to do a checkOldImpl() here, we know it's an up to date
0389: // SocketImpl!
0390: impl = new PlainSocketImpl();
0391: }
0392: if (impl != null)
0393: impl.setSocket(this );
0394: }
0395:
0396: /**
0397: * Get the <code>SocketImpl</code> attached to this socket, creating
0398: * it if necessary.
0399: *
0400: * @return the <code>SocketImpl</code> attached to that ServerSocket.
0401: * @throws SocketException if creation fails
0402: * @since 1.4
0403: */
0404: SocketImpl getImpl() throws SocketException {
0405: if (!created)
0406: createImpl(true);
0407: return impl;
0408: }
0409:
0410: /**
0411: * Connects this socket to the server.
0412: *
0413: * @param endpoint the <code>SocketAddress</code>
0414: * @throws IOException if an error occurs during the connection
0415: * @throws IllegalArgumentException if endpoint is null or is a
0416: * SocketAddress subclass not supported by this socket
0417: * @since 1.4
0418: * @spec JSR-51
0419: */
0420: public void connect(SocketAddress endpoint) throws IOException {
0421: connect(endpoint, 0);
0422: }
0423:
0424: /**
0425: * Connects this socket to the server with a specified timeout value.
0426: * A timeout of zero is interpreted as an infinite timeout. The connection
0427: * will then block until established or an error occurs.
0428: *
0429: * @param endpoint the <code>SocketAddress</code>
0430: * @param timeout the timeout value to be used in milliseconds.
0431: * @throws IOException if an error occurs during the connection
0432: * @throws SocketTimeoutException if timeout expires before connecting
0433: * @throws IllegalArgumentException if endpoint is null or is a
0434: * SocketAddress subclass not supported by this socket
0435: * @since 1.4
0436: * @spec JSR-51
0437: */
0438: public void connect(SocketAddress endpoint, int timeout)
0439: throws IOException {
0440: if (endpoint == null)
0441: throw new IllegalArgumentException(
0442: "connect: The address can't be null");
0443:
0444: if (timeout < 0)
0445: throw new IllegalArgumentException(
0446: "connect: timeout can't be negative");
0447:
0448: if (isClosed())
0449: throw new SocketException("Socket is closed");
0450:
0451: if (!oldImpl && isConnected())
0452: throw new SocketException("already connected");
0453:
0454: if (!(endpoint instanceof InetSocketAddress))
0455: throw new IllegalArgumentException(
0456: "Unsupported address type");
0457:
0458: InetSocketAddress epoint = (InetSocketAddress) endpoint;
0459:
0460: SecurityManager security = System.getSecurityManager();
0461: if (security != null) {
0462: if (epoint.isUnresolved())
0463: security.checkConnect(epoint.getHostName(), epoint
0464: .getPort());
0465: else
0466: security.checkConnect(epoint.getAddress()
0467: .getHostAddress(), epoint.getPort());
0468: }
0469: if (!created)
0470: createImpl(true);
0471: if (!oldImpl)
0472: impl.connect(epoint, timeout);
0473: else if (timeout == 0) {
0474: if (epoint.isUnresolved())
0475: impl.connect(epoint.getAddress().getHostName(), epoint
0476: .getPort());
0477: else
0478: impl.connect(epoint.getAddress(), epoint.getPort());
0479: } else
0480: throw new UnsupportedOperationException(
0481: "SocketImpl.connect(addr, timeout)");
0482: connected = true;
0483: /*
0484: * If the socket was not bound before the connect, it is now because
0485: * the kernel will have picked an ephemeral port & a local address
0486: */
0487: bound = true;
0488: }
0489:
0490: /**
0491: * Binds the socket to a local address.
0492: * <P>
0493: * If the address is <code>null</code>, then the system will pick up
0494: * an ephemeral port and a valid local address to bind the socket.
0495: *
0496: * @param bindpoint the <code>SocketAddress</code> to bind to
0497: * @throws IOException if the bind operation fails, or if the socket
0498: * is already bound.
0499: * @throws IllegalArgumentException if bindpoint is a
0500: * SocketAddress subclass not supported by this socket
0501: *
0502: * @since 1.4
0503: * @see #isBound
0504: */
0505: public void bind(SocketAddress bindpoint) throws IOException {
0506: if (isClosed())
0507: throw new SocketException("Socket is closed");
0508: if (!oldImpl && isBound())
0509: throw new SocketException("Already bound");
0510:
0511: if (bindpoint != null
0512: && (!(bindpoint instanceof InetSocketAddress)))
0513: throw new IllegalArgumentException(
0514: "Unsupported address type");
0515: InetSocketAddress epoint = (InetSocketAddress) bindpoint;
0516: if (epoint != null && epoint.isUnresolved())
0517: throw new SocketException("Unresolved address");
0518: if (bindpoint == null)
0519: getImpl().bind(InetAddress.anyLocalAddress(), 0);
0520: else
0521: getImpl().bind(epoint.getAddress(), epoint.getPort());
0522: bound = true;
0523: }
0524:
0525: /**
0526: * set the flags after an accept() call.
0527: */
0528: final void postAccept() {
0529: connected = true;
0530: created = true;
0531: bound = true;
0532: }
0533:
0534: void setCreated() {
0535: created = true;
0536: }
0537:
0538: void setBound() {
0539: bound = true;
0540: }
0541:
0542: void setConnected() {
0543: connected = true;
0544: }
0545:
0546: /**
0547: * Returns the address to which the socket is connected.
0548: *
0549: * @return the remote IP address to which this socket is connected,
0550: * or <code>null</code> if the socket is not connected.
0551: */
0552: public InetAddress getInetAddress() {
0553: if (!isConnected())
0554: return null;
0555: try {
0556: return getImpl().getInetAddress();
0557: } catch (SocketException e) {
0558: }
0559: return null;
0560: }
0561:
0562: /**
0563: * Gets the local address to which the socket is bound.
0564: *
0565: * @return the local address to which the socket is bound or
0566: * <code>InetAddress.anyLocalAddress()</code>
0567: * if the socket is not bound yet.
0568: * @since JDK1.1
0569: */
0570: public InetAddress getLocalAddress() {
0571: // This is for backward compatibility
0572: if (!isBound())
0573: return InetAddress.anyLocalAddress();
0574: InetAddress in = null;
0575: try {
0576: in = (InetAddress) getImpl().getOption(
0577: SocketOptions.SO_BINDADDR);
0578: if (in.isAnyLocalAddress()) {
0579: in = InetAddress.anyLocalAddress();
0580: }
0581: } catch (Exception e) {
0582: in = InetAddress.anyLocalAddress(); // "0.0.0.0"
0583: }
0584: return in;
0585: }
0586:
0587: /**
0588: * Returns the remote port to which this socket is connected.
0589: *
0590: * @return the remote port number to which this socket is connected, or
0591: * 0 if the socket is not connected yet.
0592: */
0593: public int getPort() {
0594: if (!isConnected())
0595: return 0;
0596: try {
0597: return getImpl().getPort();
0598: } catch (SocketException e) {
0599: // Shouldn't happen as we're connected
0600: }
0601: return -1;
0602: }
0603:
0604: /**
0605: * Returns the local port to which this socket is bound.
0606: *
0607: * @return the local port number to which this socket is bound or -1
0608: * if the socket is not bound yet.
0609: */
0610: public int getLocalPort() {
0611: if (!isBound())
0612: return -1;
0613: try {
0614: return getImpl().getLocalPort();
0615: } catch (SocketException e) {
0616: // shouldn't happen as we're bound
0617: }
0618: return -1;
0619: }
0620:
0621: /**
0622: * Returns the address of the endpoint this socket is connected to, or
0623: * <code>null</code> if it is unconnected.
0624: * @return a <code>SocketAddress</code> reprensenting the remote endpoint of this
0625: * socket, or <code>null</code> if it is not connected yet.
0626: * @see #getInetAddress()
0627: * @see #getPort()
0628: * @see #connect(SocketAddress, int)
0629: * @see #connect(SocketAddress)
0630: * @since 1.4
0631: */
0632: public SocketAddress getRemoteSocketAddress() {
0633: if (!isConnected())
0634: return null;
0635: return new InetSocketAddress(getInetAddress(), getPort());
0636: }
0637:
0638: /**
0639: * Returns the address of the endpoint this socket is bound to, or
0640: * <code>null</code> if it is not bound yet.
0641: *
0642: * @return a <code>SocketAddress</code> representing the local endpoint of this
0643: * socket, or <code>null</code> if it is not bound yet.
0644: * @see #getLocalAddress()
0645: * @see #getLocalPort()
0646: * @see #bind(SocketAddress)
0647: * @since 1.4
0648: */
0649:
0650: public SocketAddress getLocalSocketAddress() {
0651: if (!isBound())
0652: return null;
0653: return new InetSocketAddress(getLocalAddress(), getLocalPort());
0654: }
0655:
0656: /**
0657: * Returns an input stream for this socket.
0658: *
0659: * <p> If this socket has an associated channel then the resulting input
0660: * stream delegates all of its operations to the channel.
0661: *
0662: * <p>Under abnormal conditions the underlying connection may be
0663: * broken by the remote host or the network software (for example
0664: * a connection reset in the case of TCP connections). When a
0665: * broken connection is detected by the network software the
0666: * following applies to the returned input stream :-
0667: *
0668: * <ul>
0669: *
0670: * <li><p>The network software may discard bytes that are buffered
0671: * by the socket. Bytes that aren't discarded by the network
0672: * software can be read using {@link java.io.InputStream#read read}.
0673: *
0674: * <li><p>If there are no bytes buffered on the socket, or all
0675: * buffered bytes have been consumed by
0676: * {@link java.io.InputStream#read read}, then all subsequent
0677: * calls to {@link java.io.InputStream#read read} will throw an
0678: * {@link java.io.IOException IOException}.
0679: *
0680: * <li><p>If there are no bytes buffered on the socket, and the
0681: * socket has not been closed using {@link #close close}, then
0682: * {@link java.io.InputStream#available available} will
0683: * return <code>0</code>.
0684: *
0685: * </ul>
0686: *
0687: * @return an input stream for reading bytes from this socket.
0688: * @exception IOException if an I/O error occurs when creating the
0689: * input stream, the socket is closed, the socket is
0690: * not connected, or the socket input has been shutdown
0691: * using {@link #shutdownInput()}
0692: *
0693: * @revised 1.4
0694: * @spec JSR-51
0695: */
0696: public InputStream getInputStream() throws IOException {
0697: if (isClosed())
0698: throw new SocketException("Socket is closed");
0699: if (!isConnected())
0700: throw new SocketException("Socket is not connected");
0701: if (isInputShutdown())
0702: throw new SocketException("Socket input is shutdown");
0703: final Socket s = this ;
0704: InputStream is = null;
0705: try {
0706: is = (InputStream) AccessController
0707: .doPrivileged(new PrivilegedExceptionAction() {
0708: public Object run() throws IOException {
0709: return impl.getInputStream();
0710: }
0711: });
0712: } catch (java.security.PrivilegedActionException e) {
0713: throw (IOException) e.getException();
0714: }
0715: return is;
0716: }
0717:
0718: /**
0719: * Returns an output stream for this socket.
0720: *
0721: * <p> If this socket has an associated channel then the resulting output
0722: * stream delegates all of its operations to the channel.
0723: *
0724: * @return an output stream for writing bytes to this socket.
0725: * @exception IOException if an I/O error occurs when creating the
0726: * output stream or if the socket is not connected.
0727: * @revised 1.4
0728: * @spec JSR-51
0729: */
0730: public OutputStream getOutputStream() throws IOException {
0731: if (isClosed())
0732: throw new SocketException("Socket is closed");
0733: if (!isConnected())
0734: throw new SocketException("Socket is not connected");
0735: if (isOutputShutdown())
0736: throw new SocketException("Socket output is shutdown");
0737: final Socket s = this ;
0738: OutputStream os = null;
0739: try {
0740: os = (OutputStream) AccessController
0741: .doPrivileged(new PrivilegedExceptionAction() {
0742: public Object run() throws IOException {
0743: return impl.getOutputStream();
0744: }
0745: });
0746: } catch (java.security.PrivilegedActionException e) {
0747: throw (IOException) e.getException();
0748: }
0749: return os;
0750: }
0751:
0752: /**
0753: * Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
0754: *
0755: * @param on <code>true</code> to enable TCP_NODELAY,
0756: * <code>false</code> to disable.
0757: *
0758: * @exception SocketException if there is an error
0759: * in the underlying protocol, such as a TCP error.
0760: *
0761: * @since JDK1.1
0762: *
0763: * @see #getTcpNoDelay()
0764: */
0765: public void setTcpNoDelay(boolean on) throws SocketException {
0766: if (isClosed())
0767: throw new SocketException("Socket is closed");
0768: getImpl().setOption(SocketOptions.TCP_NODELAY, new Boolean(on));
0769: }
0770:
0771: /**
0772: * Tests if TCP_NODELAY is enabled.
0773: *
0774: * @return a <code>boolean</code> indicating whether or not TCP_NODELAY is enabled.
0775: * @exception SocketException if there is an error
0776: * in the underlying protocol, such as a TCP error.
0777: * @since JDK1.1
0778: * @see #setTcpNoDelay(boolean)
0779: */
0780: public boolean getTcpNoDelay() throws SocketException {
0781: if (isClosed())
0782: throw new SocketException("Socket is closed");
0783: return ((Boolean) getImpl()
0784: .getOption(SocketOptions.TCP_NODELAY)).booleanValue();
0785: }
0786:
0787: /**
0788: * Enable/disable SO_LINGER with the specified linger time in seconds.
0789: * The maximum timeout value is platform specific.
0790: *
0791: * The setting only affects socket close.
0792: *
0793: * @param on whether or not to linger on.
0794: * @param linger how long to linger for, if on is true.
0795: * @exception SocketException if there is an error
0796: * in the underlying protocol, such as a TCP error.
0797: * @exception IllegalArgumentException if the linger value is negative.
0798: * @since JDK1.1
0799: * @see #getSoLinger()
0800: */
0801: public void setSoLinger(boolean on, int linger)
0802: throws SocketException {
0803: if (isClosed())
0804: throw new SocketException("Socket is closed");
0805: if (!on) {
0806: getImpl().setOption(SocketOptions.SO_LINGER,
0807: new Boolean(on));
0808: } else {
0809: if (linger < 0) {
0810: throw new IllegalArgumentException(
0811: "invalid value for SO_LINGER");
0812: }
0813: if (linger > 65535)
0814: linger = 65535;
0815: getImpl().setOption(SocketOptions.SO_LINGER,
0816: new Integer(linger));
0817: }
0818: }
0819:
0820: /**
0821: * Returns setting for SO_LINGER. -1 returns implies that the
0822: * option is disabled.
0823: *
0824: * The setting only affects socket close.
0825: *
0826: * @return the setting for SO_LINGER.
0827: * @exception SocketException if there is an error
0828: * in the underlying protocol, such as a TCP error.
0829: * @since JDK1.1
0830: * @see #setSoLinger(boolean, int)
0831: */
0832: public int getSoLinger() throws SocketException {
0833: if (isClosed())
0834: throw new SocketException("Socket is closed");
0835: Object o = getImpl().getOption(SocketOptions.SO_LINGER);
0836: if (o instanceof Integer) {
0837: return ((Integer) o).intValue();
0838: } else {
0839: return -1;
0840: }
0841: }
0842:
0843: /**
0844: * Send one byte of urgent data on the socket. The byte to be sent is the lowest eight
0845: * bits of the data parameter. The urgent byte is
0846: * sent after any preceding writes to the socket OutputStream
0847: * and before any future writes to the OutputStream.
0848: * @param data The byte of data to send
0849: * @exception IOException if there is an error
0850: * sending the data.
0851: * @since 1.4
0852: */
0853: public void sendUrgentData(int data) throws IOException {
0854: if (!getImpl().supportsUrgentData()) {
0855: throw new SocketException("Urgent data not supported");
0856: }
0857: getImpl().sendUrgentData(data);
0858: }
0859:
0860: /**
0861: * Enable/disable OOBINLINE (receipt of TCP urgent data)
0862: *
0863: * By default, this option is disabled and TCP urgent data received on a
0864: * socket is silently discarded. If the user wishes to receive urgent data, then
0865: * this option must be enabled. When enabled, urgent data is received
0866: * inline with normal data.
0867: * <p>
0868: * Note, only limited support is provided for handling incoming urgent
0869: * data. In particular, no notification of incoming urgent data is provided
0870: * and there is no capability to distinguish between normal data and urgent
0871: * data unless provided by a higher level protocol.
0872: *
0873: * @param on <code>true</code> to enable OOBINLINE,
0874: * <code>false</code> to disable.
0875: *
0876: * @exception SocketException if there is an error
0877: * in the underlying protocol, such as a TCP error.
0878: *
0879: * @since 1.4
0880: *
0881: * @see #getOOBInline()
0882: */
0883: public void setOOBInline(boolean on) throws SocketException {
0884: if (isClosed())
0885: throw new SocketException("Socket is closed");
0886: getImpl()
0887: .setOption(SocketOptions.SO_OOBINLINE, new Boolean(on));
0888: }
0889:
0890: /**
0891: * Tests if OOBINLINE is enabled.
0892: *
0893: * @return a <code>boolean</code> indicating whether or not OOBINLINE is enabled.
0894: * @exception SocketException if there is an error
0895: * in the underlying protocol, such as a TCP error.
0896: * @since 1.4
0897: * @see #setOOBInline(boolean)
0898: */
0899: public boolean getOOBInline() throws SocketException {
0900: if (isClosed())
0901: throw new SocketException("Socket is closed");
0902: return ((Boolean) getImpl().getOption(
0903: SocketOptions.SO_OOBINLINE)).booleanValue();
0904: }
0905:
0906: /**
0907: * Enable/disable SO_TIMEOUT with the specified timeout, in
0908: * milliseconds. With this option set to a non-zero timeout,
0909: * a read() call on the InputStream associated with this Socket
0910: * will block for only this amount of time. If the timeout expires,
0911: * a <B>java.net.SocketTimeoutException</B> is raised, though the
0912: * Socket is still valid. The option <B>must</B> be enabled
0913: * prior to entering the blocking operation to have effect. The
0914: * timeout must be > 0.
0915: * A timeout of zero is interpreted as an infinite timeout.
0916: * @param timeout the specified timeout, in milliseconds.
0917: * @exception SocketException if there is an error
0918: * in the underlying protocol, such as a TCP error.
0919: * @since JDK 1.1
0920: * @see #getSoTimeout()
0921: */
0922: public synchronized void setSoTimeout(int timeout)
0923: throws SocketException {
0924: if (isClosed())
0925: throw new SocketException("Socket is closed");
0926: if (timeout < 0)
0927: throw new IllegalArgumentException(
0928: "timeout can't be negative");
0929:
0930: getImpl().setOption(SocketOptions.SO_TIMEOUT,
0931: new Integer(timeout));
0932: }
0933:
0934: /**
0935: * Returns setting for SO_TIMEOUT. 0 returns implies that the
0936: * option is disabled (i.e., timeout of infinity).
0937: * @return the setting for SO_TIMEOUT
0938: * @exception SocketException if there is an error
0939: * in the underlying protocol, such as a TCP error.
0940: * @since JDK1.1
0941: * @see #setSoTimeout(int)
0942: */
0943: public synchronized int getSoTimeout() throws SocketException {
0944: if (isClosed())
0945: throw new SocketException("Socket is closed");
0946: Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
0947: /* extra type safety */
0948: if (o instanceof Integer) {
0949: return ((Integer) o).intValue();
0950: } else {
0951: return 0;
0952: }
0953: }
0954:
0955: /**
0956: * Sets the SO_SNDBUF option to the specified value for this
0957: * <tt>Socket</tt>. The SO_SNDBUF option is used by the platform's
0958: * networking code as a hint for the size to set
0959: * the underlying network I/O buffers.
0960: *
0961: * <p>Because SO_SNDBUF is a hint, applications that want to
0962: * verify what size the buffers were set to should call
0963: * {@link #getSendBufferSize()}.
0964: *
0965: * @exception SocketException if there is an error
0966: * in the underlying protocol, such as a TCP error.
0967: *
0968: * @param size the size to which to set the send buffer
0969: * size. This value must be greater than 0.
0970: *
0971: * @exception IllegalArgumentException if the
0972: * value is 0 or is negative.
0973: *
0974: * @see #getSendBufferSize()
0975: * @since 1.2
0976: */
0977: public synchronized void setSendBufferSize(int size)
0978: throws SocketException {
0979: if (!(size > 0)) {
0980: throw new IllegalArgumentException("negative send size");
0981: }
0982: if (isClosed())
0983: throw new SocketException("Socket is closed");
0984: getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
0985: }
0986:
0987: /**
0988: * Get value of the SO_SNDBUF option for this <tt>Socket</tt>,
0989: * that is the buffer size used by the platform
0990: * for output on this <tt>Socket</tt>.
0991: * @return the value of the SO_SNDBUF option for this <tt>Socket</tt>.
0992: *
0993: * @exception SocketException if there is an error
0994: * in the underlying protocol, such as a TCP error.
0995: *
0996: * @see #setSendBufferSize(int)
0997: * @since 1.2
0998: */
0999: public synchronized int getSendBufferSize() throws SocketException {
1000: if (isClosed())
1001: throw new SocketException("Socket is closed");
1002: int result = 0;
1003: Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
1004: if (o instanceof Integer) {
1005: result = ((Integer) o).intValue();
1006: }
1007: return result;
1008: }
1009:
1010: /**
1011: * Sets the SO_RCVBUF option to the specified value for this
1012: * <tt>Socket</tt>. The SO_RCVBUF option is used by the platform's
1013: * networking code as a hint for the size to set
1014: * the underlying network I/O buffers.
1015: *
1016: * <p>Increasing the receive buffer size can increase the performance of
1017: * network I/O for high-volume connection, while decreasing it can
1018: * help reduce the backlog of incoming data.
1019: *
1020: * <p>Because SO_RCVBUF is a hint, applications that want to
1021: * verify what size the buffers were set to should call
1022: * {@link #getReceiveBufferSize()}.
1023: *
1024: * <p>The value of SO_RCVBUF is also used to set the TCP receive window
1025: * that is advertized to the remote peer. Generally, the window size
1026: * can be modified at any time when a socket is connected. However, if
1027: * a receive window larger than 64K is required then this must be requested
1028: * <B>before</B> the socket is connected to the remote peer. There are two
1029: * cases to be aware of:<p>
1030: * <ol>
1031: * <li>For sockets accepted from a ServerSocket, this must be done by calling
1032: * {@link ServerSocket#setReceiveBufferSize(int)} before the ServerSocket
1033: * is bound to a local address.<p></li>
1034: * <li>For client sockets, setReceiveBufferSize() must be called before
1035: * connecting the socket to its remote peer.<p></li></ol>
1036: * @param size the size to which to set the receive buffer
1037: * size. This value must be greater than 0.
1038: *
1039: * @exception IllegalArgumentException if the value is 0 or is
1040: * negative.
1041: *
1042: * @exception SocketException if there is an error
1043: * in the underlying protocol, such as a TCP error.
1044: *
1045: * @see #getReceiveBufferSize()
1046: * @see ServerSocket#setReceiveBufferSize(int)
1047: * @since 1.2
1048: */
1049: public synchronized void setReceiveBufferSize(int size)
1050: throws SocketException {
1051: if (size <= 0) {
1052: throw new IllegalArgumentException("invalid receive size");
1053: }
1054: if (isClosed())
1055: throw new SocketException("Socket is closed");
1056: getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
1057: }
1058:
1059: /**
1060: * Gets the value of the SO_RCVBUF option for this <tt>Socket</tt>,
1061: * that is the buffer size used by the platform for
1062: * input on this <tt>Socket</tt>.
1063: *
1064: * @return the value of the SO_RCVBUF option for this <tt>Socket</tt>.
1065: * @exception SocketException if there is an error
1066: * in the underlying protocol, such as a TCP error.
1067: * @see #setReceiveBufferSize(int)
1068: * @since 1.2
1069: */
1070: public synchronized int getReceiveBufferSize()
1071: throws SocketException {
1072: if (isClosed())
1073: throw new SocketException("Socket is closed");
1074: int result = 0;
1075: Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
1076: if (o instanceof Integer) {
1077: result = ((Integer) o).intValue();
1078: }
1079: return result;
1080: }
1081:
1082: /**
1083: * Enable/disable SO_KEEPALIVE.
1084: *
1085: * @param on whether or not to have socket keep alive turned on.
1086: * @exception SocketException if there is an error
1087: * in the underlying protocol, such as a TCP error.
1088: * @since 1.3
1089: * @see #getKeepAlive()
1090: */
1091: public void setKeepAlive(boolean on) throws SocketException {
1092: if (isClosed())
1093: throw new SocketException("Socket is closed");
1094: getImpl()
1095: .setOption(SocketOptions.SO_KEEPALIVE, new Boolean(on));
1096: }
1097:
1098: /**
1099: * Tests if SO_KEEPALIVE is enabled.
1100: *
1101: * @return a <code>boolean</code> indicating whether or not SO_KEEPALIVE is enabled.
1102: * @exception SocketException if there is an error
1103: * in the underlying protocol, such as a TCP error.
1104: * @since 1.3
1105: * @see #setKeepAlive(boolean)
1106: */
1107: public boolean getKeepAlive() throws SocketException {
1108: if (isClosed())
1109: throw new SocketException("Socket is closed");
1110: return ((Boolean) getImpl().getOption(
1111: SocketOptions.SO_KEEPALIVE)).booleanValue();
1112: }
1113:
1114: /**
1115: * Sets traffic class or type-of-service octet in the IP
1116: * header for packets sent from this Socket.
1117: * As the underlying network implementation may ignore this
1118: * value applications should consider it a hint.
1119: *
1120: * <P> The tc <B>must</B> be in the range <code> 0 <= tc <=
1121: * 255</code> or an IllegalArgumentException will be thrown.
1122: * <p>Notes:
1123: * <p> for Internet Protocol v4 the value consists of an octet
1124: * with precedence and TOS fields as detailed in RFC 1349. The
1125: * TOS field is bitset created by bitwise-or'ing values such
1126: * the following :-
1127: * <p>
1128: * <UL>
1129: * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
1130: * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
1131: * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
1132: * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
1133: * </UL>
1134: * The last low order bit is always ignored as this
1135: * corresponds to the MBZ (must be zero) bit.
1136: * <p>
1137: * Setting bits in the precedence field may result in a
1138: * SocketException indicating that the operation is not
1139: * permitted.
1140: * <p>
1141: * for Internet Protocol v6 <code>tc</code> is the value that
1142: * would be placed into the sin6_flowinfo field of the IP header.
1143: *
1144: * @param tc an <code>int</code> value for the bitset.
1145: * @throws SocketException if there is an error setting the
1146: * traffic class or type-of-service
1147: * @since 1.4
1148: * @see #getTrafficClass
1149: */
1150: public void setTrafficClass(int tc) throws SocketException {
1151: if (tc < 0 || tc > 255)
1152: throw new IllegalArgumentException(
1153: "tc is not in range 0 -- 255");
1154:
1155: if (isClosed())
1156: throw new SocketException("Socket is closed");
1157: getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
1158: }
1159:
1160: /**
1161: * Gets traffic class or type-of-service in the IP header
1162: * for packets sent from this Socket
1163: * <p>
1164: * As the underlying network implementation may ignore the
1165: * traffic class or type-of-service set using {@link #setTrafficClass()}
1166: * this method may return a different value than was previously
1167: * set using the {@link #setTrafficClass()} method on this Socket.
1168: *
1169: * @return the traffic class or type-of-service already set
1170: * @throws SocketException if there is an error obtaining the
1171: * traffic class or type-of-service value.
1172: * @since 1.4
1173: * @see #setTrafficClass
1174: */
1175: public int getTrafficClass() throws SocketException {
1176: return ((Integer) (getImpl().getOption(SocketOptions.IP_TOS)))
1177: .intValue();
1178: }
1179:
1180: /**
1181: * Enable/disable the SO_REUSEADDR socket option.
1182: * <p>
1183: * When a TCP connection is closed the connection may remain
1184: * in a timeout state for a period of time after the connection
1185: * is closed (typically known as the <tt>TIME_WAIT</tt> state
1186: * or <tt>2MSL</tt> wait state).
1187: * For applications using a well known socket address or port
1188: * it may not be possible to bind a socket to the required
1189: * <tt>SocketAddress</tt> if there is a connection in the
1190: * timeout state involving the socket address or port.
1191: * <p>
1192: * Enabling <tt>SO_REUSEADDR</tt> prior to binding the socket
1193: * using {@link #bind(SocketAddress)} allows the socket to be
1194: * bound even though a previous connection is in a timeout
1195: * state.
1196: * <p>
1197: * When a <tt>Socket</tt> is created the initial setting
1198: * of <tt>SO_REUSEADDR</tt> is disabled.
1199: * <p>
1200: * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
1201: * disabled after a socket is bound (See {@link #isBound()})
1202: * is not defined.
1203: *
1204: * @param on whether to enable or disable the socket option
1205: * @exception SocketException if an error occurs enabling or
1206: * disabling the <tt>SO_RESUEADDR</tt> socket option,
1207: * or the socket is closed.
1208: * @since 1.4
1209: * @see #getReuseAddress()
1210: * @see #bind(SocketAddress)
1211: * @see #isClosed()
1212: * @see #isBound()
1213: */
1214: public void setReuseAddress(boolean on) throws SocketException {
1215: if (isClosed())
1216: throw new SocketException("Socket is closed");
1217: getImpl()
1218: .setOption(SocketOptions.SO_REUSEADDR, new Boolean(on));
1219: }
1220:
1221: /**
1222: * Tests if SO_REUSEADDR is enabled.
1223: *
1224: * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
1225: * @exception SocketException if there is an error
1226: * in the underlying protocol, such as a TCP error.
1227: * @since 1.4
1228: * @see #setReuseAddress(boolean)
1229: */
1230: public boolean getReuseAddress() throws SocketException {
1231: if (isClosed())
1232: throw new SocketException("Socket is closed");
1233: return ((Boolean) (getImpl()
1234: .getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
1235: }
1236:
1237: /**
1238: * Closes this socket.
1239: * <p>
1240: * Any thread currently blocked in an I/O operation upon this socket
1241: * will throw a {@link SocketException}.
1242: * <p>
1243: * Once a socket has been closed, it is not available for further networking
1244: * use (i.e. can't be reconnected or rebound). A new socket needs to be
1245: * created.
1246: *
1247: * <p> If this socket has an associated channel then the channel is closed
1248: * as well.
1249: *
1250: * @exception IOException if an I/O error occurs when closing this socket.
1251: * @revised 1.4
1252: * @spec JSR-51
1253: * @see #isClosed
1254: */
1255: public synchronized void close() throws IOException {
1256: synchronized (closeLock) {
1257: if (isClosed())
1258: return;
1259: if (created)
1260: impl.close();
1261: closed = true;
1262: }
1263: }
1264:
1265: /**
1266: * Places the input stream for this socket at "end of stream".
1267: * Any data sent to the input stream side of the socket is acknowledged
1268: * and then silently discarded.
1269: * <p>
1270: * If you read from a socket input stream after invoking
1271: * shutdownInput() on the socket, the stream will return EOF.
1272: *
1273: * @exception IOException if an I/O error occurs when shutting down this
1274: * socket.
1275: *
1276: * @since 1.3
1277: * @see java.net.Socket#shutdownOutput()
1278: * @see java.net.Socket#close()
1279: * @see java.net.Socket#setSoLinger(boolean, int)
1280: * @see #isInputShutdown
1281: */
1282: public void shutdownInput() throws IOException {
1283: if (isClosed())
1284: throw new SocketException("Socket is closed");
1285: if (!isConnected())
1286: throw new SocketException("Socket is not connected");
1287: if (isInputShutdown())
1288: throw new SocketException(
1289: "Socket input is already shutdown");
1290: getImpl().shutdownInput();
1291: shutIn = true;
1292: }
1293:
1294: /**
1295: * Disables the output stream for this socket.
1296: * For a TCP socket, any previously written data will be sent
1297: * followed by TCP's normal connection termination sequence.
1298: *
1299: * If you write to a socket output stream after invoking
1300: * shutdownOutput() on the socket, the stream will throw
1301: * an IOException.
1302: *
1303: * @exception IOException if an I/O error occurs when shutting down this
1304: * socket.
1305: *
1306: * @since 1.3
1307: * @see java.net.Socket#shutdownInput()
1308: * @see java.net.Socket#close()
1309: * @see java.net.Socket#setSoLinger(boolean, int)
1310: * @see #isOutputShutdown
1311: */
1312: public void shutdownOutput() throws IOException {
1313: if (isClosed())
1314: throw new SocketException("Socket is closed");
1315: if (!isConnected())
1316: throw new SocketException("Socket is not connected");
1317: if (isOutputShutdown())
1318: throw new SocketException(
1319: "Socket output is already shutdown");
1320: getImpl().shutdownOutput();
1321: shutOut = true;
1322: }
1323:
1324: /**
1325: * Converts this socket to a <code>String</code>.
1326: *
1327: * @return a string representation of this socket.
1328: */
1329: public String toString() {
1330: try {
1331: if (isConnected())
1332: return "Socket[addr=" + getImpl().getInetAddress()
1333: + ",port=" + getImpl().getPort()
1334: + ",localport=" + getImpl().getLocalPort()
1335: + "]";
1336: } catch (SocketException e) {
1337: }
1338: return "Socket[unconnected]";
1339: }
1340:
1341: /**
1342: * Returns the connection state of the socket.
1343: *
1344: * @return true if the socket successfuly connected to a server
1345: * @since 1.4
1346: */
1347: public boolean isConnected() {
1348: // Before 1.3 Sockets were always connected during creation
1349: return connected || oldImpl;
1350: }
1351:
1352: /**
1353: * Returns the binding state of the socket.
1354: *
1355: * @return true if the socket successfuly bound to an address
1356: * @since 1.4
1357: * @see #bind
1358: */
1359: public boolean isBound() {
1360: // Before 1.3 Sockets were always bound during creation
1361: return bound || oldImpl;
1362: }
1363:
1364: /**
1365: * Returns the closed state of the socket.
1366: *
1367: * @return true if the socket has been closed
1368: * @since 1.4
1369: * @see #close
1370: */
1371: public boolean isClosed() {
1372: synchronized (closeLock) {
1373: return closed;
1374: }
1375: }
1376:
1377: /**
1378: * Returns wether the read-half of the socket connection is closed.
1379: *
1380: * @return true if the input of the socket has been shutdown
1381: * @since 1.4
1382: * @see #shutdownInput
1383: */
1384: public boolean isInputShutdown() {
1385: return shutIn;
1386: }
1387:
1388: /**
1389: * Returns wether the write-half of the socket connection is closed.
1390: *
1391: * @return true if the output of the socket has been shutdown
1392: * @since 1.4
1393: * @see #shutdownOutput
1394: */
1395: public boolean isOutputShutdown() {
1396: return shutOut;
1397: }
1398:
1399: /**
1400: * The factory for all client sockets.
1401: */
1402: private static SocketImplFactory factory = null;
1403:
1404: private static synchronized void checkSocks() {
1405: int port = -1;
1406: String socksPort = null;
1407: String useSocks = null;
1408:
1409: if (factory == null) {
1410:
1411: useSocks = (String) AccessController
1412: .doPrivileged(new sun.security.action.GetPropertyAction(
1413: "socksProxyHost"));
1414: if (useSocks == null || useSocks.length() <= 0)
1415: return;
1416:
1417: socksPort = (String) AccessController
1418: .doPrivileged(new sun.security.action.GetPropertyAction(
1419: "socksProxyPort"));
1420: if (socksPort != null && socksPort.length() > 0) {
1421: try {
1422: port = Integer.parseInt(socksPort);
1423: } catch (Exception e) {
1424: port = -1;
1425: }
1426: }
1427: if (useSocks != null)
1428: factory = new SocksSocketImplFactory(useSocks, port);
1429: } else if (factory instanceof SocksSocketImplFactory) {
1430: useSocks = (String) AccessController
1431: .doPrivileged(new sun.security.action.GetPropertyAction(
1432: "socksProxyHost"));
1433: if (useSocks == null || useSocks.length() <= 0)
1434: factory = null;
1435: }
1436: }
1437:
1438: /**
1439: * Sets the client socket implementation factory for the
1440: * application. The factory can be specified only once.
1441: * <p>
1442: * When an application creates a new client socket, the socket
1443: * implementation factory's <code>createSocketImpl</code> method is
1444: * called to create the actual socket implementation.
1445: *
1446: * <p>If there is a security manager, this method first calls
1447: * the security manager's <code>checkSetFactory</code> method
1448: * to ensure the operation is allowed.
1449: * This could result in a SecurityException.
1450: *
1451: * @param fac the desired factory.
1452: * @exception IOException if an I/O error occurs when setting the
1453: * socket factory.
1454: * @exception SocketException if the factory is already defined.
1455: * @exception SecurityException if a security manager exists and its
1456: * <code>checkSetFactory</code> method doesn't allow the operation.
1457: * @see java.net.SocketImplFactory#createSocketImpl()
1458: * @see SecurityManager#checkSetFactory
1459: */
1460: public static synchronized void setSocketImplFactory(
1461: SocketImplFactory fac) throws IOException {
1462: if (factory != null) {
1463: throw new SocketException("factory already defined");
1464: }
1465: SecurityManager security = System.getSecurityManager();
1466: if (security != null) {
1467: security.checkSetFactory();
1468: }
1469: factory = fac;
1470: }
1471: }
|