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