View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2009 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  
18  package java.net;
19  
20  import java.io.InputStream;
21  import java.io.OutputStream;
22  import java.io.IOException;
23  import java.nio.channels.SocketChannel;
24  import java.security.AccessController;
25  import java.security.PrivilegedAction;
26  import java.security.PrivilegedExceptionAction;
27  
28  
29  import ch.elca.el4j.util.socketstatistics.LoggerSocketFactory;
30  
31  /**
32   * This is a modified version of the original java class.
33   *
34   * The difference to the original Socket class is that
35   * this implementation uses the
36   * ch.elca.el4j.util.socketStatistics.LoggerSocketFactory
37   * as default SocketImplFactory.
38   *
39   * This enables logging and the generation of statistics
40   * for all used sockets.
41   *
42   *
43   * This class implements client sockets (also called just
44   * "sockets"). A socket is an endpoint for communication
45   * between two machines.
46   * <p>
47   * The actual work of the socket is performed by an instance of the
48   * <code>SocketImpl</code> class. An application, by changing
49   * the socket factory that creates the socket implementation,
50   * can configure itself to create sockets appropriate to the local
51   * firewall.
52   * 
53   * @svnLink $Revision: 4068 $;$Date: 2010-01-05 09:38:21 +0100 (Di, 05. Jan 2010) $;$Author: jonasha $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/socketstatistics/src/main/java/java/net/Socket.java $
54   * @version 1.115, 09/05/07
55   * @see	 java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
56   * @see	 java.net.SocketImpl
57   * @see	 java.nio.channels.SocketChannel
58   * @since   JDK1.0
59   */
60  
61  public class Socket {
62  	/**
63  	 * Various states of this socket.
64  	 */
65  	private boolean created = false;
66  	private boolean bound = false;
67  	private boolean connected = false;
68  	private boolean closed = false;
69  	private Object closeLock = new Object();
70  	private boolean shutIn = false;
71  	private boolean shutOut = false;
72  
73  	/**
74  	 * The implementation of this Socket.
75  	 */
76  	SocketImpl impl;
77  
78  	/**
79  	 * Are we using an older SocketImpl?
80  	 */
81  	private boolean oldImpl = false;
82  
83  	/**
84  	 * Creates an unconnected socket, with the
85  	 * system-default type of SocketImpl.
86  	 *
87  	 * @since   JDK1.1
88  	 * @revised 1.4
89  	 */
90  	public Socket() {
91  		setImpl();
92  	}
93  
94  	/**
95  	 * Creates an unconnected socket, specifying the type of proxy, if any,
96  	 * that should be used regardless of any other settings.
97  	 * <P>
98  	 * If there is a security manager, its <code>checkConnect</code> method
99  	 * is called with the proxy host address and port number
100 	 * as its arguments. This could result in a SecurityException.
101 	 * <P>
102 	 * Examples: 
103 	 * <UL> <LI><code>Socket s = new Socket(Proxy.NO_PROXY);</code> will create
104 	 * a plain socket ignoring any other proxy configuration.</LI>
105 	 * <LI><code>Socket s = new Socket(new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("socks.mydom.com", 1080)));</code>
106 	 * will create a socket connecting through the specified SOCKS proxy
107 	 * server.</LI>
108 	 * </UL>
109 	 *
110 	 * @param proxy a {@link java.net.Proxy Proxy} object specifying what kind
111 	 *			of proxying should be used.
112 	 * @throws IllegalArgumentException if the proxy is of an invalid type 
113 	 *		or <code>null</code>.
114 	 * @throws SecurityException if a security manager is present and
115 	 *				 permission to connect to the proxy is
116 	 *				 denied.
117 	 * @see java.net.ProxySelector
118 	 * @see java.net.Proxy
119 	 *
120 	 * @since   1.5
121 	 */
122 	public Socket(Proxy proxy) {
123 		// Create a copy of Proxy as a security measure
124 	if (proxy == null) {
125 		throw new IllegalArgumentException("Invalid Proxy");
126 	}
127 	Proxy p = proxy == Proxy.NO_PROXY ? proxy : sun.net.ApplicationProxy.create(proxy);
128 
129 	if (p.type() == Proxy.Type.SOCKS) {
130 		SecurityManager security = System.getSecurityManager();
131 		InetSocketAddress epoint = (InetSocketAddress) p.address();
132 		if (security != null) {
133 		if (epoint.isUnresolved())
134 			epoint = new InetSocketAddress(epoint.getHostName(), epoint.getPort());
135 		if (epoint.isUnresolved())
136 			security.checkConnect(epoint.getHostName(), epoint.getPort());
137 		else
138 			security.checkConnect(epoint.getAddress().getHostAddress(),
139 			epoint.getPort());
140 		}
141 		impl = new SocksSocketImpl(p);
142 		impl.setSocket(this);
143 	} else {
144 		if (p == Proxy.NO_PROXY) {
145 		if (factory == null) {
146 			impl = new PlainSocketImpl();
147 			impl.setSocket(this);
148 		} else
149 			setImpl();
150 		} else
151 		throw new IllegalArgumentException("Invalid Proxy");
152 	}
153 	}
154 
155 	/**
156 	 * Creates an unconnected Socket with a user-specified
157 	 * SocketImpl.
158 	 * <P>
159 	 * @param impl an instance of a <B>SocketImpl</B>
160 	 * the subclass wishes to use on the Socket.
161 	 *
162 	 * @exception SocketException if there is an error in the underlying protocol,	 
163 	 * such as a TCP error. 
164 	 * @since   JDK1.1
165 	 */
166 	protected Socket(SocketImpl impl) throws SocketException {
167 		this.impl = impl;
168 	if (impl != null) {
169 		checkOldImpl();
170 		this.impl.setSocket(this);
171 	}
172 	}
173 
174 	/**
175 	 * Creates a stream socket and connects it to the specified port
176 	 * number on the named host.
177 	 * <p>
178 	 * If the specified host is <tt>null</tt> it is the equivalent of
179 	 * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
180 	 * In other words, it is equivalent to specifying an address of the 
181 	 * loopback interface. </p>
182 	 * <p>
183 	 * If the application has specified a server socket factory, that
184 	 * factory's <code>createSocketImpl</code> method is called to create
185 	 * the actual socket implementation. Otherwise a "plain" socket is created.
186 	 * <p>
187 	 * If there is a security manager, its
188 	 * <code>checkConnect</code> method is called
189 	 * with the host address and <code>port</code> 
190 	 * as its arguments. This could result in a SecurityException.
191 	 *
192 	 * @param	  host   the host name, or <code>null</code> for the loopback address.
193 	 * @param	  port   the port number.
194 	 *
195 	 * @exception  UnknownHostException if the IP address of 
196 	 * the host could not be determined.
197 	 *
198 	 * @exception  IOException  if an I/O error occurs when creating the socket.
199 	 * @exception  SecurityException  if a security manager exists and its  
200 	 *			 <code>checkConnect</code> method doesn't allow the operation.
201 	 * @see		java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
202 	 * @see		java.net.SocketImpl
203 	 * @see		java.net.SocketImplFactory#createSocketImpl()
204 	 * @see		SecurityManager#checkConnect
205 	 */
206 	public Socket(String host, int port)
207 		throws UnknownHostException, IOException {
208 	this(host != null ? new InetSocketAddress(host, port) :
209 		new InetSocketAddress(InetAddress.getByName(null), port),
210 		(SocketAddress) null, true);
211 	}
212 
213 	/**
214 	 * Creates a stream socket and connects it to the specified port
215 	 * number at the specified IP address.
216 	 * <p>
217 	 * If the application has specified a socket factory, that factory's
218 	 * <code>createSocketImpl</code> method is called to create the
219 	 * actual socket implementation. Otherwise a "plain" socket is created.
220 	 * <p>
221 	 * If there is a security manager, its
222 	 * <code>checkConnect</code> method is called
223 	 * with the host address and <code>port</code> 
224 	 * as its arguments. This could result in a SecurityException.
225 	 * 
226 	 * @param	  address   the IP address.
227 	 * @param	  port	  the port number.
228 	 * @exception  IOException  if an I/O error occurs when creating the socket.
229 	 * @exception  SecurityException  if a security manager exists and its  
230 	 *			 <code>checkConnect</code> method doesn't allow the operation.
231 	 * @see		java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
232 	 * @see		java.net.SocketImpl
233 	 * @see		java.net.SocketImplFactory#createSocketImpl()
234 	 * @see		SecurityManager#checkConnect
235 	 */
236 	public Socket(InetAddress address, int port) throws IOException {
237 		this(address != null ? new InetSocketAddress(address, port) : null, 
238 			(SocketAddress) null, true);
239 	}
240 
241 	/**
242 	 * Creates a socket and connects it to the specified remote host on
243 	 * the specified remote port. The Socket will also bind() to the local
244 	 * address and port supplied.
245 	 * <p>
246 	 * If the specified host is <tt>null</tt> it is the equivalent of
247 	 * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
248 	 * In other words, it is equivalent to specifying an address of the 
249 	 * loopback interface. </p>
250 	 * <p>
251 	 * If there is a security manager, its
252 	 * <code>checkConnect</code> method is called
253 	 * with the host address and <code>port</code> 
254 	 * as its arguments. This could result in a SecurityException.
255 	 * 
256 	 * @param host the name of the remote host, or <code>null</code> for the loopback address.
257 	 * @param port the remote port
258 	 * @param localAddr the local address the socket is bound to
259 	 * @param localPort the local port the socket is bound to
260 	 * @exception  IOException  if an I/O error occurs when creating the socket.
261 	 * @exception  SecurityException  if a security manager exists and its  
262 	 *			 <code>checkConnect</code> method doesn't allow the operation.
263 	 * @see		SecurityManager#checkConnect
264 	 * @since   JDK1.1
265 	 */
266 	public Socket(String host, int port, InetAddress localAddr,
267 		int localPort) throws IOException {
268 		this(host != null ? new InetSocketAddress(host, port) :
269 		new InetSocketAddress(InetAddress.getByName(null), port),
270 		new InetSocketAddress(localAddr, localPort), true);
271 	}
272 
273 	/**
274 	 * Creates a socket and connects it to the specified remote address on
275 	 * the specified remote port. The Socket will also bind() to the local
276 	 * address and port supplied.
277 	 * <p>
278 	 * If there is a security manager, its
279 	 * <code>checkConnect</code> method is called
280 	 * with the host address and <code>port</code> 
281 	 * as its arguments. This could result in a SecurityException.
282 	 * 
283 	 * @param address the remote address
284 	 * @param port the remote port
285 	 * @param localAddr the local address the socket is bound to
286 	 * @param localPort the local port the socket is bound to
287 	 * @exception  IOException  if an I/O error occurs when creating the socket.
288 	 * @exception  SecurityException  if a security manager exists and its  
289 	 *			 <code>checkConnect</code> method doesn't allow the operation.
290 	 * @see		SecurityManager#checkConnect
291 	 * @since   JDK1.1
292 	 */
293 	public Socket(InetAddress address, int port, InetAddress localAddr,
294 		int localPort) throws IOException {
295 	this(address != null ? new InetSocketAddress(address, port) : null,
296 		new InetSocketAddress(localAddr, localPort), true);
297 	}
298 
299 	/**
300 	 * Creates a stream socket and connects it to the specified port
301 	 * number on the named host.
302 	 * <p>
303 	 * If the specified host is <tt>null</tt> it is the equivalent of
304 	 * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
305 	 * In other words, it is equivalent to specifying an address of the 
306 	 * loopback interface. </p>
307 	 * <p>
308 	 * If the stream argument is <code>true</code>, this creates a
309 	 * stream socket. If the stream argument is <code>false</code>, it
310 	 * creates a datagram socket.
311 	 * <p>
312 	 * If the application has specified a server socket factory, that
313 	 * factory's <code>createSocketImpl</code> method is called to create
314 	 * the actual socket implementation. Otherwise a "plain" socket is created.
315 	 * <p>
316 	 * If there is a security manager, its
317 	 * <code>checkConnect</code> method is called
318 	 * with the host address and <code>port</code> 
319 	 * as its arguments. This could result in a SecurityException.
320 	 * <p>
321 	 * If a UDP socket is used, TCP/IP related socket options will not apply.
322 	 *
323 	 * @param	  host	 the host name, or <code>null</code> for the loopback address.
324 	 * @param	  port	 the port number.
325 	 * @param	  stream   a <code>boolean</code> indicating whether this is
326 	 *					  a stream socket or a datagram socket.
327 	 * @exception  IOException  if an I/O error occurs when creating the socket.
328 	 * @exception  SecurityException  if a security manager exists and its  
329 	 *			 <code>checkConnect</code> method doesn't allow the operation.
330 	 * @see		java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
331 	 * @see		java.net.SocketImpl
332 	 * @see		java.net.SocketImplFactory#createSocketImpl()
333 	 * @see		SecurityManager#checkConnect
334 	 * @deprecated Use DatagramSocket instead for UDP transport.
335 	 */
336 	@Deprecated
337 	public Socket(String host, int port, boolean stream) throws IOException {
338 	this(host != null ? new InetSocketAddress(host, port) :
339 		new InetSocketAddress(InetAddress.getByName(null), port),
340 		(SocketAddress) null, stream);
341 	}
342 
343 	/**
344 	 * Creates a socket and connects it to the specified port number at
345 	 * the specified IP address.
346 	 * <p>
347 	 * If the stream argument is <code>true</code>, this creates a
348 	 * stream socket. If the stream argument is <code>false</code>, it
349 	 * creates a datagram socket.
350 	 * <p>
351 	 * If the application has specified a server socket factory, that
352 	 * factory's <code>createSocketImpl</code> method is called to create
353 	 * the actual socket implementation. Otherwise a "plain" socket is created.
354 	 * 
355 	 * <p>If there is a security manager, its
356 	 * <code>checkConnect</code> method is called
357 	 * with <code>host.getHostAddress()</code> and <code>port</code> 
358 	 * as its arguments. This could result in a SecurityException.
359 	 * <p>
360 	 * If UDP socket is used, TCP/IP related socket options will not apply.
361 	 *
362 	 * @param	  host	 the IP address.
363 	 * @param	  port	  the port number.
364 	 * @param	  stream	if <code>true</code>, create a stream socket;
365 	 *					   otherwise, create a datagram socket.
366 	 * @exception  IOException  if an I/O error occurs when creating the socket.
367 	 * @exception  SecurityException  if a security manager exists and its  
368 	 *			 <code>checkConnect</code> method doesn't allow the operation.
369 	 * @see		java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
370 	 * @see		java.net.SocketImpl
371 	 * @see		java.net.SocketImplFactory#createSocketImpl()
372 	 * @see		SecurityManager#checkConnect
373 	 * @deprecated Use DatagramSocket instead for UDP transport.
374 	 */
375 	@Deprecated
376 	public Socket(InetAddress host, int port, boolean stream) throws IOException {
377 	this(host != null ? new InetSocketAddress(host, port) : null,
378 		new InetSocketAddress(0), stream);
379 	}
380 
381 	private Socket(SocketAddress address, SocketAddress localAddr,
382 		boolean stream) throws IOException {
383 	setImpl();
384 
385 	// backward compatibility
386 	if (address == null)
387 		throw new NullPointerException();
388 
389 	try {
390 		createImpl(stream);
391 		if (localAddr != null)
392 		bind(localAddr);
393 		if (address != null)
394 		connect(address);
395 	} catch (IOException e) {
396 		close();
397 		throw e;
398 	}
399 	}
400 
401 	/**
402 	 * Creates the socket implementation.
403 	 *
404 	 * @param stream a <code>boolean</code> value : <code>true</code> for a TCP socket,
405 	 *			 <code>false</code> for UDP.
406 	 * @throws IOException if creation fails
407 	 * @since 1.4
408 	 */
409 	void createImpl(boolean stream) throws SocketException {
410 	if (impl == null) 
411 		setImpl();
412 	try {
413 		impl.create(stream);
414 		created = true;
415 	} catch (IOException e) {
416 		throw new SocketException(e.getMessage());
417 	}
418 	}
419 
420 	private void checkOldImpl() {
421 	if (impl == null)
422 		return;
423 	// SocketImpl.connect() is a protected method, therefore we need to use
424 	// getDeclaredMethod, therefore we need permission to access the member
425 
426 		oldImpl = AccessController.doPrivileged
427 				(new PrivilegedAction<Boolean>() {
428 		public Boolean run() {
429 			Class[] cl = new Class[2];
430 			cl[0] = SocketAddress.class;
431 			cl[1] = Integer.TYPE;
432 			Class clazz = impl.getClass();
433 			while (true) {
434 			try {
435 				clazz.getDeclaredMethod("connect", cl);
436 				return Boolean.FALSE;
437 			} catch (NoSuchMethodException e) {
438 				clazz = clazz.getSuperclass();
439 			// java.net.SocketImpl class will always have this abstract method.
440 			// If we have not found it by now in the hierarchy then it does not
441 			// exist, we are an old style impl.
442 			if (clazz.equals(java.net.SocketImpl.class)) {
443 							return Boolean.TRUE;
444 						}
445 			}
446 			}
447 		}
448 		});
449 	}
450 
451 	/**
452 	 * Sets impl to the system-default type of SocketImpl.
453 	 * @since 1.4
454 	 */
455 	void setImpl() {
456 	if (factory != null) {
457 		impl = factory.createSocketImpl();
458 		checkOldImpl();
459 	} else {
460 		// No need to do a checkOldImpl() here, we know it's an up to date
461 		// SocketImpl!
462 		impl = new SocksSocketImpl();
463 	}
464 	if (impl != null)
465 		impl.setSocket(this);
466 	}
467 
468 
469 	/**
470 	 * Get the <code>SocketImpl</code> attached to this socket, creating
471 	 * it if necessary.
472 	 *
473 	 * @return	the <code>SocketImpl</code> attached to that ServerSocket.
474 	 * @throws SocketException if creation fails
475 	 * @since 1.4
476 	 */
477 	SocketImpl getImpl() throws SocketException {
478 	if (!created)
479 		createImpl(true);
480 	return impl;
481 	}
482 
483 	/**
484 	 * Connects this socket to the server.
485 	 *
486 	 * @param	endpoint the <code>SocketAddress</code>
487 	 * @throws	IOException if an error occurs during the connection
488 	 * @throws  java.nio.channels.IllegalBlockingModeException
489 	 *		  if this socket has an associated channel,
490 	 *		  and the channel is in non-blocking mode
491 	 * @throws  IllegalArgumentException if endpoint is null or is a
492 	 *		  SocketAddress subclass not supported by this socket
493 	 * @since 1.4
494 	 * @spec JSR-51
495 	 */
496 	public void connect(SocketAddress endpoint) throws IOException {
497 	connect(endpoint, 0);
498 	}
499 
500 	/**
501 	 * Connects this socket to the server with a specified timeout value.
502 	 * A timeout of zero is interpreted as an infinite timeout. The connection
503 	 * will then block until established or an error occurs.
504 	 *
505 	 * @param	endpoint the <code>SocketAddress</code>
506 	 * @param	timeout  the timeout value to be used in milliseconds.
507 	 * @throws	IOException if an error occurs during the connection
508 	 * @throws	SocketTimeoutException if timeout expires before connecting
509 	 * @throws  java.nio.channels.IllegalBlockingModeException
510 	 *		  if this socket has an associated channel,
511 	 *		  and the channel is in non-blocking mode
512 	 * @throws  IllegalArgumentException if endpoint is null or is a
513 	 *		  SocketAddress subclass not supported by this socket
514 	 * @since 1.4
515 	 * @spec JSR-51
516 	 */
517 	public void connect(SocketAddress endpoint, int timeout) throws IOException {
518 	if (endpoint == null)
519 		throw new IllegalArgumentException("connect: The address can't be null");
520 
521 	if (timeout < 0)
522 		throw new IllegalArgumentException("connect: timeout can't be negative");
523 
524 	if (isClosed())
525 		throw new SocketException("Socket is closed");
526 
527 	if (!oldImpl && isConnected())
528 		throw new SocketException("already connected");
529 
530 	if (!(endpoint instanceof InetSocketAddress))
531 		throw new IllegalArgumentException("Unsupported address type");
532 
533 	InetSocketAddress epoint = (InetSocketAddress) endpoint;
534 
535 	SecurityManager security = System.getSecurityManager();
536 	if (security != null) {
537 		if (epoint.isUnresolved())
538 		security.checkConnect(epoint.getHostName(),
539 			epoint.getPort());
540 		else
541 		security.checkConnect(epoint.getAddress().getHostAddress(),
542 			epoint.getPort());
543 	}
544 	if (!created)
545 		createImpl(true);
546 	if (!oldImpl)
547 		impl.connect(epoint, timeout);
548 	else if (timeout == 0) {
549 		if (epoint.isUnresolved())
550 		impl.connect(epoint.getAddress().getHostName(),
551 			epoint.getPort());
552 		else
553 		impl.connect(epoint.getAddress(), epoint.getPort());
554 	} else
555 		throw new UnsupportedOperationException("SocketImpl.connect(addr, timeout)");
556 	connected = true;
557 	/*
558 	 * If the socket was not bound before the connect, it is now because
559 	 * the kernel will have picked an ephemeral port & a local address
560 	 */
561 	bound = true;
562 	}
563 
564 	/**
565 	 * Binds the socket to a local address.
566 	 * <P>
567 	 * If the address is <code>null</code>, then the system will pick up
568 	 * an ephemeral port and a valid local address to bind the socket.
569 	 *
570 	 * @param	bindpoint the <code>SocketAddress</code> to bind to
571 	 * @throws	IOException if the bind operation fails, or if the socket
572 	 *			   is already bound.
573 	 * @throws  IllegalArgumentException if bindpoint is a
574 	 *		  SocketAddress subclass not supported by this socket
575 	 *
576 	 * @since	1.4
577 	 * @see #isBound
578 	 */
579 	public void bind(SocketAddress bindpoint) throws IOException {
580 	if (isClosed())
581 		throw new SocketException("Socket is closed");
582 	if (!oldImpl && isBound())
583 		throw new SocketException("Already bound");
584 
585 	if (bindpoint != null && (!(bindpoint instanceof InetSocketAddress)))
586 		throw new IllegalArgumentException("Unsupported address type");
587 	InetSocketAddress epoint = (InetSocketAddress) bindpoint;
588 	if (epoint != null && epoint.isUnresolved())
589 		throw new SocketException("Unresolved address");
590 	if (bindpoint == null)
591 		getImpl().bind(InetAddress.anyLocalAddress(), 0);
592 	else
593 		getImpl().bind(epoint.getAddress(),
594 			epoint.getPort());
595 	bound = true;
596 	}
597 
598 	/**
599 	 * set the flags after an accept() call.
600 	 */
601 	final void postAccept() { 
602 	connected = true;
603 	created = true;
604 	bound = true;
605 	}
606 
607 	void setCreated() {
608 	created = true;
609 	}
610 
611 	void setBound() {
612 	bound = true;
613 	}
614 
615 	void setConnected() {
616 	connected = true;
617 	}
618 
619 	/**
620 	 * Returns the address to which the socket is connected.
621 	 *
622 	 * @return  the remote IP address to which this socket is connected,
623 	 *		or <code>null</code> if the socket is not connected.
624 	 */
625 	public InetAddress getInetAddress() {
626 	if (!isConnected())
627 		return null;
628 	try {
629 		return getImpl().getInetAddress();
630 	} catch (SocketException e) {
631 	}
632 	return null;
633 	}
634 
635 	/**
636 	 * Gets the local address to which the socket is bound.
637 	 *
638 	 * @return the local address to which the socket is bound or 
639 	 *		   <code>InetAddress.anyLocalAddress()</code>
640 	 *		   if the socket is not bound yet.
641 	 * @since   JDK1.1
642 	 */
643 	public InetAddress getLocalAddress() {
644 	// This is for backward compatibility
645 	if (!isBound())
646 		return InetAddress.anyLocalAddress();
647 	InetAddress in = null;
648 	try {
649 		in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
650 		if (in.isAnyLocalAddress()) {
651 		in = InetAddress.anyLocalAddress();
652 		}
653 	} catch (Exception e) {
654 		in = InetAddress.anyLocalAddress(); // "0.0.0.0"
655 	}
656 	return in;
657 	}
658 
659 	/**
660 	 * Returns the remote port to which this socket is connected.
661 	 *
662 	 * @return  the remote port number to which this socket is connected, or
663 	 *			0 if the socket is not connected yet.
664 	 */
665 	public int getPort() {
666 	if (!isConnected())
667 		return 0;
668 	try {
669 		return getImpl().getPort();
670 	} catch (SocketException e) {
671 		// Shouldn't happen as we're connected
672 	}
673 	return -1;
674 	}
675 
676 	/**
677 	 * Returns the local port to which this socket is bound.
678 	 *
679 	 * @return  the local port number to which this socket is bound or -1
680 	 *			if the socket is not bound yet.
681 	 */
682 	public int getLocalPort() {
683 	if (!isBound())
684 		return -1;
685 	try {
686 		return getImpl().getLocalPort();
687 	} catch(SocketException e) {
688 		// shouldn't happen as we're bound
689 	}
690 	return -1;
691 	}
692 
693 	/**
694 	 * Returns the address of the endpoint this socket is connected to, or
695 	 * <code>null</code> if it is unconnected.
696 	 * @return a <code>SocketAddress</code> reprensenting the remote endpoint of this
697 	 *		   socket, or <code>null</code> if it is not connected yet.
698 	 * @see #getInetAddress()
699 	 * @see #getPort()
700 	 * @see #connect(SocketAddress, int)
701 	 * @see #connect(SocketAddress)
702 	 * @since 1.4
703 	 */
704 	public SocketAddress getRemoteSocketAddress() {
705 	if (!isConnected())
706 		return null;
707 	return new InetSocketAddress(getInetAddress(), getPort());
708 	}
709 
710 	/**
711 	 * Returns the address of the endpoint this socket is bound to, or
712 	 * <code>null</code> if it is not bound yet.
713 	 *
714 	 * @return a <code>SocketAddress</code> representing the local endpoint of this
715 	 *		   socket, or <code>null</code> if it is not bound yet.
716 	 * @see #getLocalAddress()
717 	 * @see #getLocalPort()
718 	 * @see #bind(SocketAddress)
719 	 * @since 1.4
720 	 */
721 
722 	public SocketAddress getLocalSocketAddress() {
723 	if (!isBound())
724 		return null;
725 	return new InetSocketAddress(getLocalAddress(), getLocalPort());
726 	}
727 
728 	/**
729 	 * Returns the unique {@link java.nio.channels.SocketChannel SocketChannel}
730 	 * object associated with this socket, if any.
731 	 *
732 	 * <p> A socket will have a channel if, and only if, the channel itself was
733 	 * created via the {@link java.nio.channels.SocketChannel#open
734 	 * SocketChannel.open} or {@link
735 	 * java.nio.channels.ServerSocketChannel#accept ServerSocketChannel.accept}
736 	 * methods.
737 	 *
738 	 * @return  the socket channel associated with this socket,
739 	 *		  or <tt>null</tt> if this socket was not created
740 	 *		  for a channel
741 	 *
742 	 * @since 1.4
743 	 * @spec JSR-51
744 	 */
745 	public SocketChannel getChannel() {
746 	return null;
747 	}
748 
749 	/**
750 	 * Returns an input stream for this socket.
751 	 *
752 	 * <p> If this socket has an associated channel then the resulting input
753 	 * stream delegates all of its operations to the channel.  If the channel
754 	 * is in non-blocking mode then the input stream's <tt>read</tt> operations
755 	 * will throw an {@link java.nio.channels.IllegalBlockingModeException}.
756 	 *
757 	 * <p>Under abnormal conditions the underlying connection may be
758 	 * broken by the remote host or the network software (for example
759 	 * a connection reset in the case of TCP connections). When a
760 	 * broken connection is detected by the network software the
761 	 * following applies to the returned input stream :-
762 	 *
763 	 * <ul>
764 	 *
765 	 *   <li><p>The network software may discard bytes that are buffered
766 	 *   by the socket. Bytes that aren't discarded by the network 
767 	 *   software can be read using {@link java.io.InputStream#read read}.
768 	 *
769 	 *   <li><p>If there are no bytes buffered on the socket, or all
770 	 *   buffered bytes have been consumed by  
771 	 *   {@link java.io.InputStream#read read}, then all subsequent
772 	 *   calls to {@link java.io.InputStream#read read} will throw an 
773 	 *   {@link java.io.IOException IOException}. 
774 	 *
775 	 *   <li><p>If there are no bytes buffered on the socket, and the
776 	 *   socket has not been closed using {@link #close close}, then
777 	 *   {@link java.io.InputStream#available available} will
778 	 *   return <code>0</code>.
779 	 *
780 	 * </ul>
781 	 *
782 	 * <p> Closing the returned {@link java.io.InputStream InputStream}
783 	 * will close the associated socket.
784 	 *
785 	 * @return	 an input stream for reading bytes from this socket.
786 	 * @exception  IOException  if an I/O error occurs when creating the
787 	 *			 input stream, the socket is closed, the socket is
788 	 *			 not connected, or the socket input has been shutdown
789 	 *			 using {@link #shutdownInput()}
790 	 *
791 	 * @revised 1.4
792 	 * @spec JSR-51
793 	 */
794 	public InputStream getInputStream() throws IOException {
795 	if (isClosed())
796 		throw new SocketException("Socket is closed");
797 	if (!isConnected())
798 		throw new SocketException("Socket is not connected");
799 	if (isInputShutdown())
800 		throw new SocketException("Socket input is shutdown");
801 	// final Socket s = this;
802 	InputStream is = null;
803 	try {
804 		is = (InputStream)
805 		AccessController.doPrivileged(new PrivilegedExceptionAction() {
806 			public Object run() throws IOException {
807 			return impl.getInputStream();
808 			}
809 		});
810 	} catch (java.security.PrivilegedActionException e) {
811 		throw (IOException) e.getException();
812 	}
813 	return is;
814 	}
815 
816 	/**
817 	 * Returns an output stream for this socket.
818 	 *
819 	 * <p> If this socket has an associated channel then the resulting output
820 	 * stream delegates all of its operations to the channel.  If the channel
821 	 * is in non-blocking mode then the output stream's <tt>write</tt>
822 	 * operations will throw an {@link
823 	 * java.nio.channels.IllegalBlockingModeException}.
824 	 *
825 	 * <p> Closing the returned {@link java.io.OutputStream OutputStream}
826 	 * will close the associated socket.
827 	 *
828 	 * @return	 an output stream for writing bytes to this socket.
829 	 * @exception  IOException  if an I/O error occurs when creating the
830 	 *			   output stream or if the socket is not connected.
831 	 * @revised 1.4
832 	 * @spec JSR-51
833 	 */
834 	public OutputStream getOutputStream() throws IOException {
835 	if (isClosed())
836 		throw new SocketException("Socket is closed");
837 	if (!isConnected())
838 		throw new SocketException("Socket is not connected");
839 	if (isOutputShutdown())
840 		throw new SocketException("Socket output is shutdown");
841 	// final Socket s = this;
842 	OutputStream os = null;
843 	try {
844 		os = (OutputStream)
845 		AccessController.doPrivileged(new PrivilegedExceptionAction() {
846 			public Object run() throws IOException {
847 			return impl.getOutputStream();
848 			}
849 		});
850 	} catch (java.security.PrivilegedActionException e) {
851 		throw (IOException) e.getException();
852 	}
853 	return os;
854 	}
855 
856 	/**
857 	 * Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
858 	 *
859 	 * @param on <code>true</code> to enable TCP_NODELAY, 
860 	 * <code>false</code> to disable.
861 	 *
862 	 * @exception SocketException if there is an error 
863 	 * in the underlying protocol, such as a TCP error.
864 	 * 
865 	 * @since   JDK1.1
866 	 *
867 	 * @see #getTcpNoDelay()
868 	 */
869 	public void setTcpNoDelay(boolean on) throws SocketException {
870 	if (isClosed())
871 		throw new SocketException("Socket is closed");
872 	getImpl().setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
873 	}
874 
875 	/**
876 	 * Tests if TCP_NODELAY is enabled.
877 	 *
878 	 * @return a <code>boolean</code> indicating whether or not TCP_NODELAY is enabled.
879 	 * @exception SocketException if there is an error
880 	 * in the underlying protocol, such as a TCP error. 
881 	 * @since   JDK1.1
882 	 * @see #setTcpNoDelay(boolean)
883 	 */
884 	public boolean getTcpNoDelay() throws SocketException {
885 	if (isClosed())
886 		throw new SocketException("Socket is closed");
887 	return ((Boolean) getImpl().getOption(SocketOptions.TCP_NODELAY)).booleanValue();
888 	}
889 
890 	/**
891 	 * Enable/disable SO_LINGER with the specified linger time in seconds. 
892 	 * The maximum timeout value is platform specific.
893 	 *
894 	 * The setting only affects socket close.
895 	 * 
896 	 * @param on	 whether or not to linger on.
897 	 * @param linger how long to linger for, if on is true.
898 	 * @exception SocketException if there is an error
899 	 * in the underlying protocol, such as a TCP error. 
900 	 * @exception IllegalArgumentException if the linger value is negative.
901 	 * @since JDK1.1
902 	 * @see #getSoLinger()
903 	 */
904 	public void setSoLinger(boolean on, int linger) throws SocketException {
905 	if (isClosed())
906 		throw new SocketException("Socket is closed");
907 	if (!on) {
908 		getImpl().setOption(SocketOptions.SO_LINGER, new Boolean(on));
909 	} else {
910 		if (linger < 0) {
911 		throw new IllegalArgumentException("invalid value for SO_LINGER");
912 		}
913 			if (linger > 65535) {
914 				getImpl().setOption(SocketOptions.SO_LINGER, new Integer(65535));
915 			} else {
916 				getImpl().setOption(SocketOptions.SO_LINGER, new Integer(linger));
917 			}
918 	}
919 	}
920 
921 	/**
922 	 * Returns setting for SO_LINGER. -1 returns implies that the
923 	 * option is disabled.
924 	 *
925 	 * The setting only affects socket close.
926 	 *
927 	 * @return the setting for SO_LINGER.
928 	 * @exception SocketException if there is an error
929 	 * in the underlying protocol, such as a TCP error. 
930 	 * @since   JDK1.1
931 	 * @see #setSoLinger(boolean, int)
932 	 */
933 	public int getSoLinger() throws SocketException {
934 	if (isClosed())
935 		throw new SocketException("Socket is closed");
936 	Object o = getImpl().getOption(SocketOptions.SO_LINGER);
937 	if (o instanceof Integer) {
938 		return ((Integer) o).intValue();
939 	} else {
940 		return -1;
941 	}
942 	}
943 
944 	/**
945 	 * Send one byte of urgent data on the socket. The byte to be sent is the lowest eight
946 	 * bits of the data parameter. The urgent byte is
947 	 * sent after any preceding writes to the socket OutputStream
948 	 * and before any future writes to the OutputStream.
949 	 * @param data The byte of data to send
950 	 * @exception IOException if there is an error
951 	 *  sending the data.
952 	 * @since 1.4
953 	 */
954 	public void sendUrgentData (int data) throws IOException  {
955 		if (!getImpl().supportsUrgentData ()) {
956 			throw new SocketException ("Urgent data not supported");
957 		}
958 		getImpl().sendUrgentData (data);
959 	}
960 
961 	/**
962 	 * Enable/disable OOBINLINE (receipt of TCP urgent data)
963 	 *
964 	 * By default, this option is disabled and TCP urgent data received on a 
965 	 * socket is silently discarded. If the user wishes to receive urgent data, then
966 	 * this option must be enabled. When enabled, urgent data is received
967 	 * inline with normal data. 
968 	 * <p>
969 	 * Note, only limited support is provided for handling incoming urgent 
970 	 * data. In particular, no notification of incoming urgent data is provided 
971 	 * and there is no capability to distinguish between normal data and urgent
972 	 * data unless provided by a higher level protocol.
973 	 *
974 	 * @param on <code>true</code> to enable OOBINLINE, 
975 	 * <code>false</code> to disable.
976 	 *
977 	 * @exception SocketException if there is an error 
978 	 * in the underlying protocol, such as a TCP error.
979 	 * 
980 	 * @since   1.4
981 	 *
982 	 * @see #getOOBInline()
983 	 */
984 	public void setOOBInline(boolean on) throws SocketException {
985 	if (isClosed())
986 		throw new SocketException("Socket is closed");
987 	getImpl().setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(on));
988 	}
989 
990 	/**
991 	 * Tests if OOBINLINE is enabled.
992 	 *
993 	 * @return a <code>boolean</code> indicating whether or not OOBINLINE is enabled.
994 	 * @exception SocketException if there is an error
995 	 * in the underlying protocol, such as a TCP error. 
996 	 * @since   1.4
997 	 * @see #setOOBInline(boolean)
998 	 */
999 	public boolean getOOBInline() throws SocketException {
1000 	if (isClosed())
1001 		throw new SocketException("Socket is closed");
1002 	return ((Boolean) getImpl().getOption(SocketOptions.SO_OOBINLINE)).booleanValue();
1003 	}
1004 
1005 	/**
1006 	 *  Enable/disable SO_TIMEOUT with the specified timeout, in
1007 	 *  milliseconds.  With this option set to a non-zero timeout,
1008 	 *  a read() call on the InputStream associated with this Socket
1009 	 *  will block for only this amount of time.  If the timeout expires,
1010 	 *  a <B>java.net.SocketTimeoutException</B> is raised, though the
1011 	 *  Socket is still valid. The option <B>must</B> be enabled
1012 	 *  prior to entering the blocking operation to have effect. The
1013 	 *  timeout must be > 0.
1014 	 *  A timeout of zero is interpreted as an infinite timeout.
1015 	 * @param timeout the specified timeout, in milliseconds.
1016 	 * @exception SocketException if there is an error
1017 	 * in the underlying protocol, such as a TCP error. 
1018 	 * @since   JDK 1.1
1019 	 * @see #getSoTimeout()
1020 	 */
1021 	public synchronized void setSoTimeout(int timeout) throws SocketException {
1022 	if (isClosed())
1023 		throw new SocketException("Socket is closed");
1024 	if (timeout < 0)
1025 		throw new IllegalArgumentException("timeout can't be negative");
1026 
1027 	getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
1028 	}
1029 
1030 	/**
1031 	 * Returns setting for SO_TIMEOUT.  0 returns implies that the
1032 	 * option is disabled (i.e., timeout of infinity).
1033 	 * @return the setting for SO_TIMEOUT
1034 	 * @exception SocketException if there is an error
1035 	 * in the underlying protocol, such as a TCP error. 
1036 	 * @since   JDK1.1
1037 	 * @see #setSoTimeout(int)
1038 	 */
1039 	public synchronized int getSoTimeout() throws SocketException {
1040 	if (isClosed())
1041 		throw new SocketException("Socket is closed");
1042 	Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
1043 	/* extra type safety */
1044 	if (o instanceof Integer) {
1045 		return ((Integer) o).intValue();
1046 	} else {
1047 		return 0;
1048 	}
1049 	}
1050 
1051 	/**
1052 	 * Sets the SO_SNDBUF option to the specified value for this
1053 	 * <tt>Socket</tt>. The SO_SNDBUF option is used by the platform's
1054 	 * networking code as a hint for the size to set
1055 	 * the underlying network I/O buffers.
1056 	 *
1057 	 * <p>Because SO_SNDBUF is a hint, applications that want to
1058 	 * verify what size the buffers were set to should call
1059 	 * {@link #getSendBufferSize()}.
1060 	 *
1061 	 * @exception SocketException if there is an error
1062 	 * in the underlying protocol, such as a TCP error. 
1063 	 *
1064 	 * @param size the size to which to set the send buffer
1065 	 * size. This value must be greater than 0.
1066 	 *
1067 	 * @exception IllegalArgumentException if the 
1068 	 * value is 0 or is negative.
1069 	 *
1070 	 * @see #getSendBufferSize()
1071 	 * @since 1.2
1072 	 */
1073 	public synchronized void setSendBufferSize(int size)
1074 	throws SocketException{
1075 	if (!(size > 0)) {
1076 		throw new IllegalArgumentException("negative send size");
1077 	}
1078 	if (isClosed())
1079 		throw new SocketException("Socket is closed");
1080 	getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
1081 	}
1082 
1083 	/**
1084 	 * Get value of the SO_SNDBUF option for this <tt>Socket</tt>, 
1085 	 * that is the buffer size used by the platform 
1086 	 * for output on this <tt>Socket</tt>.
1087 	 * @return the value of the SO_SNDBUF option for this <tt>Socket</tt>.
1088 	 *
1089 	 * @exception SocketException if there is an error
1090 	 * in the underlying protocol, such as a TCP error. 
1091 	 *
1092 	 * @see #setSendBufferSize(int)
1093 	 * @since 1.2
1094 	 */
1095 	public synchronized int getSendBufferSize() throws SocketException {
1096 	if (isClosed())
1097 		throw new SocketException("Socket is closed");
1098 	int result = 0;
1099 	Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
1100 	if (o instanceof Integer) {
1101 		result = ((Integer)o).intValue();
1102 	}
1103 	return result;
1104 	}
1105 
1106 	/**
1107 	 * Sets the SO_RCVBUF option to the specified value for this
1108 	 * <tt>Socket</tt>. The SO_RCVBUF option is used by the platform's
1109 	 * networking code as a hint for the size to set
1110 	 * the underlying network I/O buffers.
1111 	 *
1112 	 * <p>Increasing the receive buffer size can increase the performance of
1113 	 * network I/O for high-volume connection, while decreasing it can
1114 	 * help reduce the backlog of incoming data. 
1115 	 *
1116 	 * <p>Because SO_RCVBUF is a hint, applications that want to
1117 	 * verify what size the buffers were set to should call
1118 	 * {@link #getReceiveBufferSize()}.
1119 	 *
1120 	 * <p>The value of SO_RCVBUF is also used to set the TCP receive window
1121 	 * that is advertized to the remote peer. Generally, the window size
1122 	 * can be modified at any time when a socket is connected. However, if
1123 	 * a receive window larger than 64K is required then this must be requested
1124 	 * <B>before</B> the socket is connected to the remote peer. There are two
1125 	 * cases to be aware of:<p>
1126 	 * <ol>
1127 	 * <li>For sockets accepted from a ServerSocket, this must be done by calling
1128 	 * {@link ServerSocket#setReceiveBufferSize(int)} before the ServerSocket 
1129 	 * is bound to a local address.<p></li>
1130 	 * <li>For client sockets, setReceiveBufferSize() must be called before
1131 	 * connecting the socket to its remote peer.<p></li></ol>
1132 	 * @param size the size to which to set the receive buffer
1133 	 * size. This value must be greater than 0.
1134 	 *
1135 	 * @exception IllegalArgumentException if the value is 0 or is
1136 	 * negative.
1137 	 *
1138 	 * @exception SocketException if there is an error
1139 	 * in the underlying protocol, such as a TCP error.
1140 	 * 
1141 	 * @see #getReceiveBufferSize()
1142 	 * @see ServerSocket#setReceiveBufferSize(int)
1143 	 * @since 1.2
1144 	 */
1145 	public synchronized void setReceiveBufferSize(int size)
1146 	throws SocketException{
1147 	if (size <= 0) {
1148 		throw new IllegalArgumentException("invalid receive size");
1149 	}
1150 	if (isClosed())
1151 		throw new SocketException("Socket is closed");
1152 	getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
1153 	}
1154 
1155 	/**
1156 	 * Gets the value of the SO_RCVBUF option for this <tt>Socket</tt>, 
1157 	 * that is the buffer size used by the platform for 
1158 	 * input on this <tt>Socket</tt>.
1159 	 *
1160 	 * @return the value of the SO_RCVBUF option for this <tt>Socket</tt>.
1161 	 * @exception SocketException if there is an error
1162 	 * in the underlying protocol, such as a TCP error. 
1163 	 * @see #setReceiveBufferSize(int)
1164 	 * @since 1.2
1165 	 */
1166 	public synchronized int getReceiveBufferSize()
1167 	throws SocketException{
1168 	if (isClosed())
1169 		throw new SocketException("Socket is closed");
1170 	int result = 0;
1171 	Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
1172 	if (o instanceof Integer) {
1173 		result = ((Integer)o).intValue();
1174 	}
1175 	return result;
1176 	}
1177 
1178 	/**
1179 	 * Enable/disable SO_KEEPALIVE.
1180 	 * 
1181 	 * @param on	 whether or not to have socket keep alive turned on.
1182 	 * @exception SocketException if there is an error
1183 	 * in the underlying protocol, such as a TCP error. 
1184 	 * @since 1.3 
1185 	 * @see #getKeepAlive()
1186 	 */
1187 	public void setKeepAlive(boolean on) throws SocketException {
1188 	if (isClosed())
1189 		throw new SocketException("Socket is closed");
1190 		getImpl().setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(on));
1191 	}
1192 
1193 	/**
1194 	 * Tests if SO_KEEPALIVE is enabled.
1195 	 *
1196 	 * @return a <code>boolean</code> indicating whether or not SO_KEEPALIVE is enabled.
1197 	 * @exception SocketException if there is an error
1198 	 * in the underlying protocol, such as a TCP error. 
1199 	 * @since   1.3
1200 	 * @see #setKeepAlive(boolean)
1201 	 */
1202 	public boolean getKeepAlive() throws SocketException {
1203 	if (isClosed())
1204 		throw new SocketException("Socket is closed");
1205 	return ((Boolean) getImpl().getOption(SocketOptions.SO_KEEPALIVE)).booleanValue();
1206 	}
1207 
1208 	/**
1209 	 * Sets traffic class or type-of-service octet in the IP
1210 	 * header for packets sent from this Socket.
1211 	 * As the underlying network implementation may ignore this
1212 	 * value applications should consider it a hint.
1213 	 *
1214 	 * <P> The tc <B>must</B> be in the range <code> 0 <= tc <=
1215 	 * 255</code> or an IllegalArgumentException will be thrown.
1216 	 * <p>Notes:
1217 	 * <p> For Internet Protocol v4 the value consists of an octet
1218 	 * with precedence and TOS fields as detailed in RFC 1349. The
1219 	 * TOS field is bitset created by bitwise-or'ing values such
1220 	 * the following :-
1221 	 * <p>
1222 	 * <UL>
1223 	 * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
1224 	 * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
1225 	 * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
1226 	 * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
1227 	 * </UL>
1228 	 * The last low order bit is always ignored as this
1229 	 * corresponds to the MBZ (must be zero) bit.
1230 	 * <p>
1231 	 * Setting bits in the precedence field may result in a
1232 	 * SocketException indicating that the operation is not
1233 	 * permitted.
1234 	 * <p>
1235 	 * As RFC 1122 section 4.2.4.2 indicates, a compliant TCP
1236 	 * implementation should, but is not required to, let application
1237 	 * change the TOS field during the lifetime of a connection.
1238 	 * So whether the type-of-service field can be changed after the
1239 	 * TCP connection has been established depends on the implementation
1240 	 * in the underlying platform. Applications should not assume that
1241 	 * they can change the TOS field after the connection.
1242 	 * <p>
1243 	 * For Internet Protocol v6 <code>tc</code> is the value that
1244 	 * would be placed into the sin6_flowinfo field of the IP header.
1245 	 *
1246 	 * @param tc		an <code>int</code> value for the bitset.
1247 	 * @throws SocketException if there is an error setting the
1248 	 * traffic class or type-of-service
1249 	 * @since 1.4
1250 	 * @see #getTrafficClass
1251 	 */
1252 	public void setTrafficClass(int tc) throws SocketException {
1253 	if (tc < 0 || tc > 255)
1254 		throw new IllegalArgumentException("tc is not in range 0 -- 255");
1255 
1256 	if (isClosed())
1257 		throw new SocketException("Socket is closed");
1258 		getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
1259 	}
1260 
1261 	/**
1262 	 * Gets traffic class or type-of-service in the IP header
1263 	 * for packets sent from this Socket
1264 	 * <p>
1265 	 * As the underlying network implementation may ignore the
1266 	 * traffic class or type-of-service set using {@link #setTrafficClass(int)}
1267 	 * this method may return a different value than was previously
1268 	 * set using the {@link #setTrafficClass(int)} method on this Socket.
1269 	 *
1270 	 * @return the traffic class or type-of-service already set
1271 	 * @throws SocketException if there is an error obtaining the
1272 	 * traffic class or type-of-service value.
1273 	 * @since 1.4
1274 	 * @see #setTrafficClass(int)
1275 	 */
1276 	public int getTrafficClass() throws SocketException {
1277 		return ((Integer) (getImpl().getOption(SocketOptions.IP_TOS))).intValue();
1278 	}
1279 
1280 	/**
1281 	 * Enable/disable the SO_REUSEADDR socket option.
1282 	 * <p>
1283 	 * When a TCP connection is closed the connection may remain
1284 	 * in a timeout state for a period of time after the connection
1285 	 * is closed (typically known as the <tt>TIME_WAIT</tt> state
1286 	 * or <tt>2MSL</tt> wait state).
1287 	 * For applications using a well known socket address or port 
1288 	 * it may not be possible to bind a socket to the required
1289 	 * <tt>SocketAddress</tt> if there is a connection in the
1290 	 * timeout state involving the socket address or port.
1291 	 * <p>
1292 	 * Enabling <tt>SO_REUSEADDR</tt> prior to binding the socket
1293 	 * using {@link #bind(SocketAddress)} allows the socket to be
1294 	 * bound even though a previous connection is in a timeout
1295 	 * state.
1296 	 * <p>
1297 	 * When a <tt>Socket</tt> is created the initial setting
1298 	 * of <tt>SO_REUSEADDR</tt> is disabled.
1299 	 * <p>
1300 	 * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
1301 	 * disabled after a socket is bound (See {@link #isBound()})
1302 	 * is not defined.
1303 	 * 
1304 	 * @param on  whether to enable or disable the socket option
1305 	 * @exception SocketException if an error occurs enabling or
1306 	 *			disabling the <tt>SO_RESUEADDR</tt> socket option,
1307 	 *		  or the socket is closed.
1308 	 * @since 1.4
1309 	 * @see #getReuseAddress()	 
1310 	 * @see #bind(SocketAddress)
1311 	 * @see #isClosed()
1312 	 * @see #isBound()
1313 	 */
1314 	public void setReuseAddress(boolean on) throws SocketException {
1315 	if (isClosed())
1316 		throw new SocketException("Socket is closed");
1317 		getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
1318 	}
1319 
1320 	/**
1321 	 * Tests if SO_REUSEADDR is enabled.
1322 	 *
1323 	 * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
1324 	 * @exception SocketException if there is an error
1325 	 * in the underlying protocol, such as a TCP error. 
1326 	 * @since   1.4
1327 	 * @see #setReuseAddress(boolean)
1328 	 */
1329 	public boolean getReuseAddress() throws SocketException {
1330 	if (isClosed())
1331 		throw new SocketException("Socket is closed");
1332 	return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
1333 	}
1334 
1335 	/**
1336 	 * Closes this socket.
1337 	 * <p>
1338 	 * Any thread currently blocked in an I/O operation upon this socket
1339 	 * will throw a {@link SocketException}.
1340 	 * <p>
1341 	 * Once a socket has been closed, it is not available for further networking
1342 	 * use (i.e. can't be reconnected or rebound). A new socket needs to be
1343 	 * created.
1344 	 *
1345 	 * <p> Closing this socket will also close the socket's
1346 	 * {@link java.io.InputStream InputStream} and
1347 	 * {@link java.io.OutputStream OutputStream}.
1348 	 *
1349 	 * <p> If this socket has an associated channel then the channel is closed
1350 	 * as well.
1351 	 *
1352 	 * @exception  IOException  if an I/O error occurs when closing this socket.
1353 	 * @revised 1.4
1354 	 * @spec JSR-51
1355 	 * @see #isClosed
1356 	 */
1357 	public synchronized void close() throws IOException {
1358 	synchronized(closeLock) {
1359 		if (isClosed())
1360 		return;
1361 		if (created)
1362 		impl.close();
1363 		closed = true;
1364 	}
1365 	}
1366 
1367 	/**
1368 	 * Places the input stream for this socket at "end of stream".
1369 	 * Any data sent to the input stream side of the socket is acknowledged
1370 	 * and then silently discarded.
1371 	 * <p>
1372 	 * If you read from a socket input stream after invoking 
1373 	 * shutdownInput() on the socket, the stream will return EOF.
1374 	 *
1375 	 * @exception IOException if an I/O error occurs when shutting down this
1376 	 * socket.
1377 	 *
1378 	 * @since 1.3
1379 	 * @see java.net.Socket#shutdownOutput()
1380 	 * @see java.net.Socket#close()
1381 	 * @see java.net.Socket#setSoLinger(boolean, int)
1382 	 * @see #isInputShutdown
1383 	 */
1384 	public void shutdownInput() throws IOException
1385 	{
1386 	if (isClosed())
1387 		throw new SocketException("Socket is closed");
1388 	if (!isConnected())
1389 		throw new SocketException("Socket is not connected");
1390 	if (isInputShutdown())
1391 		throw new SocketException("Socket input is already shutdown");
1392 	getImpl().shutdownInput();
1393 	shutIn = true;
1394 	}
1395 	
1396 	/**
1397 	 * Disables the output stream for this socket.
1398 	 * For a TCP socket, any previously written data will be sent
1399 	 * followed by TCP's normal connection termination sequence.
1400 	 *
1401 	 * If you write to a socket output stream after invoking 
1402 	 * shutdownOutput() on the socket, the stream will throw 
1403 	 * an IOException.
1404 	 *
1405 	 * @exception IOException if an I/O error occurs when shutting down this
1406 	 * socket.
1407 	 *
1408 	 * @since 1.3
1409 	 * @see java.net.Socket#shutdownInput()
1410 	 * @see java.net.Socket#close()
1411 	 * @see java.net.Socket#setSoLinger(boolean, int)
1412 	 * @see #isOutputShutdown
1413 	 */
1414 	public void shutdownOutput() throws IOException
1415 	{
1416 	if (isClosed())
1417 		throw new SocketException("Socket is closed");
1418 	if (!isConnected())
1419 		throw new SocketException("Socket is not connected");
1420 	if (isOutputShutdown())
1421 		throw new SocketException("Socket output is already shutdown");
1422 	getImpl().shutdownOutput();
1423 	shutOut = true;
1424 	}
1425 
1426 	/**
1427 	 * Converts this socket to a <code>String</code>.
1428 	 *
1429 	 * @return  a string representation of this socket.
1430 	 */
1431 	public String toString() {
1432 	try {
1433 		if (isConnected())
1434 		return "Socket[addr=" + getImpl().getInetAddress() +
1435 			",port=" + getImpl().getPort() +
1436 			",localport=" + getImpl().getLocalPort() + "]";
1437 	} catch (SocketException e) {
1438 	}
1439 	return "Socket[unconnected]";
1440 	}
1441 
1442 	/**
1443 	 * Returns the connection state of the socket.
1444 	 *
1445 	 * @return true if the socket successfuly connected to a server
1446 	 * @since 1.4
1447 	 */
1448 	public boolean isConnected() {
1449 	// Before 1.3 Sockets were always connected during creation
1450 	return connected || oldImpl;
1451 	}
1452 
1453 	/**
1454 	 * Returns the binding state of the socket.
1455 	 *
1456 	 * @return true if the socket successfuly bound to an address
1457 	 * @since 1.4
1458 	 * @see #bind
1459 	 */
1460 	public boolean isBound() {
1461 	// Before 1.3 Sockets were always bound during creation
1462 	return bound || oldImpl;
1463 	}
1464 
1465 	/**
1466 	 * Returns the closed state of the socket.
1467 	 *
1468 	 * @return true if the socket has been closed
1469 	 * @since 1.4
1470 	 * @see #close
1471 	 */
1472 	public boolean isClosed() {
1473 	synchronized(closeLock) {
1474 		return closed;
1475 	}
1476 	}
1477 
1478 	/**
1479 	 * Returns whether the read-half of the socket connection is closed.
1480 	 *
1481 	 * @return true if the input of the socket has been shutdown
1482 	 * @since 1.4
1483 	 * @see #shutdownInput
1484 	 */
1485 	public boolean isInputShutdown() {
1486 	return shutIn;
1487 	}
1488 
1489 	/**
1490 	 * Returns whether the write-half of the socket connection is closed.
1491 	 *
1492 	 * @return true if the output of the socket has been shutdown
1493 	 * @since 1.4
1494 	 * @see #shutdownOutput
1495 	 */
1496 	public boolean isOutputShutdown() {
1497 	return shutOut;
1498 	}
1499 
1500 	/**
1501 	 * The factory for all client sockets.
1502 	 */
1503 	/**
1504 	 * Modification to use LoggerSocketFactory as default.
1505 	 * private static SocketImplFactory factory = null;
1506 	 */
1507 	private static SocketImplFactory factory = new LoggerSocketFactory();
1508 
1509 	
1510 	/**
1511 	 * Sets the client socket implementation factory for the
1512 	 * application. The factory can be specified only once.
1513 	 * <p>
1514 	 * When an application creates a new client socket, the socket
1515 	 * implementation factory's <code>createSocketImpl</code> method is
1516 	 * called to create the actual socket implementation.
1517 	 * <p>
1518 	 * Passing <code>null</code> to the method is a no-op unless the factory
1519 	 * was already set.
1520 	 * <p>If there is a security manager, this method first calls
1521 	 * the security manager's <code>checkSetFactory</code> method 
1522 	 * to ensure the operation is allowed. 
1523 	 * This could result in a SecurityException.
1524 	 *
1525 	 * @param	  fac   the desired factory.
1526 	 * @exception  IOException  if an I/O error occurs when setting the
1527 	 *			   socket factory.
1528 	 * @exception  SocketException  if the factory is already defined.
1529 	 * @exception  SecurityException  if a security manager exists and its  
1530 	 *			 <code>checkSetFactory</code> method doesn't allow the operation.
1531 	 * @see		java.net.SocketImplFactory#createSocketImpl()
1532 	 * @see		SecurityManager#checkSetFactory
1533 	 */
1534 	public static synchronized void setSocketImplFactory(SocketImplFactory fac)
1535 	throws IOException
1536 	{
1537 	if (factory != null) {
1538 		throw new SocketException("factory already defined");
1539 	}
1540 	SecurityManager security = System.getSecurityManager();
1541 	if (security != null) {
1542 		security.checkSetFactory();
1543 	}
1544 	factory = fac;
1545 	}
1546 
1547 	/**
1548 	 * Sets performance preferences for this socket.
1549 	 *
1550 	 * <p> Sockets use the TCP/IP protocol by default.  Some implementations
1551 	 * may offer alternative protocols which have different performance
1552 	 * characteristics than TCP/IP.  This method allows the application to
1553 	 * express its own preferences as to how these tradeoffs should be made
1554 	 * when the implementation chooses from the available protocols.
1555 	 *
1556 	 * <p> Performance preferences are described by three integers
1557 	 * whose values indicate the relative importance of short connection time,
1558 	 * low latency, and high bandwidth.  The absolute values of the integers
1559 	 * are irrelevant; in order to choose a protocol the values are simply
1560 	 * compared, with larger values indicating stronger preferences. Negative
1561 	 * values represent a lower priority than positive values. If the
1562 	 * application prefers short connection time over both low latency and high
1563 	 * bandwidth, for example, then it could invoke this method with the values
1564 	 * <tt>(1, 0, 0)</tt>.  If the application prefers high bandwidth above low
1565 	 * latency, and low latency above short connection time, then it could
1566 	 * invoke this method with the values <tt>(0, 1, 2)</tt>.
1567 	 *
1568 	 * <p> Invoking this method after this socket has been connected
1569 	 * will have no effect.
1570 	 *
1571 	 * @param  connectionTime
1572 	 *		 An <tt>int</tt> expressing the relative importance of a short
1573 	 *		 connection time
1574 	 *
1575 	 * @param  latency
1576 	 *		 An <tt>int</tt> expressing the relative importance of low
1577 	 *		 latency
1578 	 *
1579 	 * @param  bandwidth
1580 	 *		 An <tt>int</tt> expressing the relative importance of high
1581 	 *		 bandwidth
1582 	 *  
1583 	 * @since 1.5
1584 	 */
1585 	public void setPerformancePreferences(int connectionTime,
1586 		int latency,
1587 		int bandwidth) {
1588 	/* Not implemented yet */
1589 	}
1590 }