KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > net > Socket


1 /*
2  * @(#)Socket.java 1.112 07/09/11
3  *
4  * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.net;
9
10 import java.io.InputStream JavaDoc;
11 import java.io.OutputStream JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.io.InterruptedIOException JavaDoc;
14 import java.nio.channels.SocketChannel JavaDoc;
15 import java.security.AccessController JavaDoc;
16 import java.security.PrivilegedExceptionAction JavaDoc;
17 import java.security.PrivilegedAction JavaDoc;
18
19 /**
20  * This class implements client sockets (also called just
21  * "sockets"). A socket is an endpoint for communication
22  * between two machines.
23  * <p>
24  * The actual work of the socket is performed by an instance of the
25  * <code>SocketImpl</code> class. An application, by changing
26  * the socket factory that creates the socket implementation,
27  * can configure itself to create sockets appropriate to the local
28  * firewall.
29  *
30  * @author unascribed
31  * @version 1.112, 09/11/07
32  * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
33  * @see java.net.SocketImpl
34  * @see java.nio.channels.SocketChannel
35  * @since JDK1.0
36  */

37 public
38 class Socket {
39     /**
40      * Various states of this socket.
41      */

42     private boolean created = false;
43     private boolean bound = false;
44     private boolean connected = false;
45     private boolean closed = false;
46     private Object JavaDoc closeLock = new Object JavaDoc();
47     private boolean shutIn = false;
48     private boolean shutOut = false;
49
50     /**
51      * The implementation of this Socket.
52      */

53     SocketImpl JavaDoc impl;
54
55     /**
56      * Are we using an older SocketImpl?
57      */

58     private boolean oldImpl = false;
59
60     /**
61      * Creates an unconnected socket, with the
62      * system-default type of SocketImpl.
63      *
64      * @since JDK1.1
65      * @revised 1.4
66      */

67     public Socket() {
68     setImpl();
69     }
70
71     /**
72      * Creates an unconnected socket, specifying the type of proxy, if any,
73      * that should be used regardless of any other settings.
74      * <P>
75      * If there is a security manager, its <code>checkConnect</code> method
76      * is called with the proxy host address and port number
77      * as its arguments. This could result in a SecurityException.
78      * <P>
79      * Examples:
80      * <UL> <LI><code>Socket s = new Socket(Proxy.NO_PROXY);</code> will create
81      * a plain socket ignoring any other proxy configuration.</LI>
82      * <LI><code>Socket s = new Socket(new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("socks.mydom.com", 1080)));</code>
83      * will create a socket connecting through the specified SOCKS proxy
84      * server.</LI>
85      * </UL>
86      *
87      * @param proxy a {@link java.net.Proxy Proxy} object specifying what kind
88      * of proxying should be used.
89      * @throws IllegalArgumentException if the proxy is of an invalid type
90      * or <code>null</code>.
91      * @throws SecurityException if a security manager is present and
92      * permission to connect to the proxy is
93      * denied.
94      * @see java.net.ProxySelector
95      * @see java.net.Proxy
96      *
97      * @since 1.5
98      */

99     public Socket(Proxy JavaDoc proxy) {
100     if (proxy != null && proxy.type() == Proxy.Type.SOCKS) {
101         SecurityManager JavaDoc security = System.getSecurityManager();
102         InetSocketAddress JavaDoc epoint = (InetSocketAddress JavaDoc) proxy.address();
103         if (security != null) {
104         if (epoint.isUnresolved())
105             epoint = new InetSocketAddress JavaDoc(epoint.getHostName(), epoint.getPort());
106                 if (epoint.isUnresolved())
107                     security.checkConnect(epoint.getHostName(), epoint.getPort());
108                 else
109             security.checkConnect(epoint.getAddress().getHostAddress(),
110                           epoint.getPort());
111         }
112         impl = new SocksSocketImpl JavaDoc(proxy);
113         impl.setSocket(this);
114     } else {
115         if (proxy == Proxy.NO_PROXY) {
116         if (factory == null) {
117             impl = new PlainSocketImpl JavaDoc();
118             impl.setSocket(this);
119         } else
120             setImpl();
121         } else
122         throw new IllegalArgumentException JavaDoc("Invalid Proxy");
123     }
124     }
125
126     /**
127      * Creates an unconnected Socket with a user-specified
128      * SocketImpl.
129      * <P>
130      * @param impl an instance of a <B>SocketImpl</B>
131      * the subclass wishes to use on the Socket.
132      *
133      * @exception SocketException if there is an error in the underlying protocol,
134      * such as a TCP error.
135      * @since JDK1.1
136      */

137     protected Socket(SocketImpl JavaDoc impl) throws SocketException JavaDoc {
138     this.impl = impl;
139     if (impl != null) {
140         checkOldImpl();
141         this.impl.setSocket(this);
142     }
143     }
144
145     /**
146      * Creates a stream socket and connects it to the specified port
147      * number on the named host.
148      * <p>
149      * If the specified host is <tt>null</tt> it is the equivalent of
150      * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
151      * In other words, it is equivalent to specifying an address of the
152      * loopback interface. </p>
153      * <p>
154      * If the application has specified a server socket factory, that
155      * factory's <code>createSocketImpl</code> method is called to create
156      * the actual socket implementation. Otherwise a "plain" socket is created.
157      * <p>
158      * If there is a security manager, its
159      * <code>checkConnect</code> method is called
160      * with the host address and <code>port</code>
161      * as its arguments. This could result in a SecurityException.
162      *
163      * @param host the host name, or <code>null</code> for the loopback address.
164      * @param port the port number.
165      *
166      * @exception UnknownHostException if the IP address of
167      * the host could not be determined.
168      *
169      * @exception IOException if an I/O error occurs when creating the socket.
170      * @exception SecurityException if a security manager exists and its
171      * <code>checkConnect</code> method doesn't allow the operation.
172      * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
173      * @see java.net.SocketImpl
174      * @see java.net.SocketImplFactory#createSocketImpl()
175      * @see SecurityManager#checkConnect
176      */

177     public Socket(String JavaDoc host, int port)
178     throws UnknownHostException JavaDoc, IOException JavaDoc
179     {
180     this(host != null ? new InetSocketAddress JavaDoc(host, port) :
181          new InetSocketAddress JavaDoc(InetAddress.getByName(null), port),
182          new InetSocketAddress JavaDoc(0), true);
183     }
184
185     /**
186      * Creates a stream socket and connects it to the specified port
187      * number at the specified IP address.
188      * <p>
189      * If the application has specified a socket factory, that factory's
190      * <code>createSocketImpl</code> method is called to create the
191      * actual socket implementation. Otherwise a "plain" socket is created.
192      * <p>
193      * If there is a security manager, its
194      * <code>checkConnect</code> method is called
195      * with the host address and <code>port</code>
196      * as its arguments. This could result in a SecurityException.
197      *
198      * @param address the IP address.
199      * @param port the port number.
200      * @exception IOException if an I/O error occurs when creating the socket.
201      * @exception SecurityException if a security manager exists and its
202      * <code>checkConnect</code> method doesn't allow the operation.
203      * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
204      * @see java.net.SocketImpl
205      * @see java.net.SocketImplFactory#createSocketImpl()
206      * @see SecurityManager#checkConnect
207      */

208     public Socket(InetAddress JavaDoc address, int port) throws IOException JavaDoc {
209     this(address != null ? new InetSocketAddress JavaDoc(address, port) : null,
210          new InetSocketAddress JavaDoc(0), true);
211     }
212
213     /**
214      * Creates a socket and connects it to the specified remote host on
215      * the specified remote port. The Socket will also bind() to the local
216      * address and port supplied.
217      * <p>
218      * If the specified host is <tt>null</tt> it is the equivalent of
219      * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
220      * In other words, it is equivalent to specifying an address of the
221      * loopback interface. </p>
222      * <p>
223      * If there is a security manager, its
224      * <code>checkConnect</code> method is called
225      * with the host address and <code>port</code>
226      * as its arguments. This could result in a SecurityException.
227      *
228      * @param host the name of the remote host, or <code>null</code> for the loopback address.
229      * @param port the remote port
230      * @param localAddr the local address the socket is bound to
231      * @param localPort the local port the socket is bound to
232      * @exception IOException if an I/O error occurs when creating the socket.
233      * @exception SecurityException if a security manager exists and its
234      * <code>checkConnect</code> method doesn't allow the operation.
235      * @see SecurityManager#checkConnect
236      * @since JDK1.1
237      */

238     public Socket(String JavaDoc host, int port, InetAddress JavaDoc localAddr,
239           int localPort) throws IOException JavaDoc {
240     this(host != null ? new InetSocketAddress JavaDoc(host, port) :
241            new InetSocketAddress JavaDoc(InetAddress.getByName(null), port),
242          new InetSocketAddress JavaDoc(localAddr, localPort), true);
243     }
244
245     /**
246      * Creates a socket and connects it to the specified remote address on
247      * the specified remote port. The Socket will also bind() to the local
248      * address and port supplied.
249      * <p>
250      * If there is a security manager, its
251      * <code>checkConnect</code> method is called
252      * with the host address and <code>port</code>
253      * as its arguments. This could result in a SecurityException.
254      *
255      * @param address the remote address
256      * @param port the remote port
257      * @param localAddr the local address the socket is bound to
258      * @param localPort the local port the socket is bound to
259      * @exception IOException if an I/O error occurs when creating the socket.
260      * @exception SecurityException if a security manager exists and its
261      * <code>checkConnect</code> method doesn't allow the operation.
262      * @see SecurityManager#checkConnect
263      * @since JDK1.1
264      */

265     public Socket(InetAddress JavaDoc address, int port, InetAddress JavaDoc localAddr,
266           int localPort) throws IOException JavaDoc {
267     this(address != null ? new InetSocketAddress JavaDoc(address, port) : null,
268          new InetSocketAddress JavaDoc(localAddr, localPort), true);
269     }
270
271     /**
272      * Creates a stream socket and connects it to the specified port
273      * number on the named host.
274      * <p>
275      * If the specified host is <tt>null</tt> it is the equivalent of
276      * specifying the address as <tt>{@link java.net.InetAddress#getByName InetAddress.getByName}(null)</tt>.
277      * In other words, it is equivalent to specifying an address of the
278      * loopback interface. </p>
279      * <p>
280      * If the stream argument is <code>true</code>, this creates a
281      * stream socket. If the stream argument is <code>false</code>, it
282      * creates a datagram socket.
283      * <p>
284      * If the application has specified a server socket factory, that
285      * factory's <code>createSocketImpl</code> method is called to create
286      * the actual socket implementation. Otherwise a "plain" socket is created.
287      * <p>
288      * If there is a security manager, its
289      * <code>checkConnect</code> method is called
290      * with the host address and <code>port</code>
291      * as its arguments. This could result in a SecurityException.
292      * <p>
293      * If a UDP socket is used, TCP/IP related socket options will not apply.
294      *
295      * @param host the host name, or <code>null</code> for the loopback address.
296      * @param port the port number.
297      * @param stream a <code>boolean</code> indicating whether this is
298      * a stream socket or a datagram socket.
299      * @exception IOException if an I/O error occurs when creating the socket.
300      * @exception SecurityException if a security manager exists and its
301      * <code>checkConnect</code> method doesn't allow the operation.
302      * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
303      * @see java.net.SocketImpl
304      * @see java.net.SocketImplFactory#createSocketImpl()
305      * @see SecurityManager#checkConnect
306      * @deprecated Use DatagramSocket instead for UDP transport.
307      */

308     @Deprecated JavaDoc
309     public Socket(String JavaDoc host, int port, boolean stream) throws IOException JavaDoc {
310     this(host != null ? new InetSocketAddress JavaDoc(host, port) :
311            new InetSocketAddress JavaDoc(InetAddress.getByName(null), port),
312          new InetSocketAddress JavaDoc(0), stream);
313     }
314
315     /**
316      * Creates a socket and connects it to the specified port number at
317      * the specified IP address.
318      * <p>
319      * If the stream argument is <code>true</code>, this creates a
320      * stream socket. If the stream argument is <code>false</code>, it
321      * creates a datagram socket.
322      * <p>
323      * If the application has specified a server socket factory, that
324      * factory's <code>createSocketImpl</code> method is called to create
325      * the actual socket implementation. Otherwise a "plain" socket is created.
326      *
327      * <p>If there is a security manager, its
328      * <code>checkConnect</code> method is called
329      * with <code>host.getHostAddress()</code> and <code>port</code>
330      * as its arguments. This could result in a SecurityException.
331      * <p>
332      * If UDP socket is used, TCP/IP related socket options will not apply.
333      *
334      * @param host the IP address.
335      * @param port the port number.
336      * @param stream if <code>true</code>, create a stream socket;
337      * otherwise, create a datagram socket.
338      * @exception IOException if an I/O error occurs when creating the socket.
339      * @exception SecurityException if a security manager exists and its
340      * <code>checkConnect</code> method doesn't allow the operation.
341      * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
342      * @see java.net.SocketImpl
343      * @see java.net.SocketImplFactory#createSocketImpl()
344      * @see SecurityManager#checkConnect
345      * @deprecated Use DatagramSocket instead for UDP transport.
346      */

347     @Deprecated JavaDoc
348     public Socket(InetAddress JavaDoc host, int port, boolean stream) throws IOException JavaDoc {
349     this(host != null ? new InetSocketAddress JavaDoc(host, port) : null,
350          new InetSocketAddress JavaDoc(0), stream);
351     }
352
353     private Socket(SocketAddress JavaDoc address, SocketAddress JavaDoc localAddr,
354            boolean stream) throws IOException JavaDoc {
355     setImpl();
356
357     // backward compatibility
358
if (address == null)
359         throw new NullPointerException JavaDoc();
360
361     try {
362         createImpl(stream);
363         if (localAddr == null)
364         localAddr = new InetSocketAddress JavaDoc(0);
365         bind(localAddr);
366         if (address != null)
367         connect(address);
368     } catch (IOException JavaDoc e) {
369         close();
370         throw e;
371     }
372     }
373
374     /**
375      * Creates the socket implementation.
376      *
377      * @param stream a <code>boolean</code> value : <code>true</code> for a TCP socket,
378      * <code>false</code> for UDP.
379      * @throws IOException if creation fails
380      * @since 1.4
381      */

382      void createImpl(boolean stream) throws SocketException JavaDoc {
383     if (impl == null)
384         setImpl();
385     try {
386         impl.create(stream);
387         created = true;
388     } catch (IOException JavaDoc e) {
389         throw new SocketException JavaDoc(e.getMessage());
390     }
391     }
392
393     private void checkOldImpl() {
394         if (impl == null)
395             return;
396         // SocketImpl.connect() is a protected method, therefore we need to use
397
// getDeclaredMethod, therefore we need permission to access the member
398

399         Boolean JavaDoc tmpBool = (Boolean JavaDoc) AccessController.doPrivileged (new PrivilegedAction JavaDoc() {
400             public Boolean JavaDoc run() {
401                 Class JavaDoc[] cl = new Class JavaDoc[2];
402                 cl[0] = SocketAddress JavaDoc.class;
403                 cl[1] = Integer.TYPE;
404                 Class JavaDoc clazz = impl.getClass();
405                 while (true) {
406                     try {
407                         clazz.getDeclaredMethod("connect", cl);
408                         return Boolean.FALSE;
409                     } catch (NoSuchMethodException JavaDoc e) {
410                         clazz = clazz.getSuperclass();
411             // java.net.SocketImpl class will always have this abstract method.
412
// If we have not found it by now in the hierarchy then it does not
413
// exist, we are an old style impl.
414
if (clazz.equals(java.net.SocketImpl JavaDoc.class)) {
415                             return Boolean.TRUE;
416                         }
417                     }
418                 }
419             }
420         });
421         oldImpl = tmpBool.booleanValue();
422     }
423     
424     /**
425      * Sets impl to the system-default type of SocketImpl.
426      * @since 1.4
427      */

428     void setImpl() {
429     if (factory != null) {
430         impl = factory.createSocketImpl();
431         checkOldImpl();
432     } else {
433         // No need to do a checkOldImpl() here, we know it's an up to date
434
// SocketImpl!
435
impl = new SocksSocketImpl JavaDoc();
436     }
437     if (impl != null)
438         impl.setSocket(this);
439     }
440
441
442     /**
443      * Get the <code>SocketImpl</code> attached to this socket, creating
444      * it if necessary.
445      *
446      * @return the <code>SocketImpl</code> attached to that ServerSocket.
447      * @throws SocketException if creation fails
448      * @since 1.4
449      */

450     SocketImpl JavaDoc getImpl() throws SocketException JavaDoc {
451     if (!created)
452         createImpl(true);
453     return impl;
454     }
455
456     /**
457      * Connects this socket to the server.
458      *
459      * @param endpoint the <code>SocketAddress</code>
460      * @throws IOException if an error occurs during the connection
461      * @throws java.nio.channels.IllegalBlockingModeException
462      * if this socket has an associated channel,
463      * and the channel is in non-blocking mode
464      * @throws IllegalArgumentException if endpoint is null or is a
465      * SocketAddress subclass not supported by this socket
466      * @since 1.4
467      * @spec JSR-51
468      */

469     public void connect(SocketAddress JavaDoc endpoint) throws IOException JavaDoc {
470     connect(endpoint, 0);
471     }
472
473     /**
474      * Connects this socket to the server with a specified timeout value.
475      * A timeout of zero is interpreted as an infinite timeout. The connection
476      * will then block until established or an error occurs.
477      *
478      * @param endpoint the <code>SocketAddress</code>
479      * @param timeout the timeout value to be used in milliseconds.
480      * @throws IOException if an error occurs during the connection
481      * @throws SocketTimeoutException if timeout expires before connecting
482      * @throws java.nio.channels.IllegalBlockingModeException
483      * if this socket has an associated channel,
484      * and the channel is in non-blocking mode
485      * @throws IllegalArgumentException if endpoint is null or is a
486      * SocketAddress subclass not supported by this socket
487      * @since 1.4
488      * @spec JSR-51
489      */

490     public void connect(SocketAddress JavaDoc endpoint, int timeout) throws IOException JavaDoc {
491     if (endpoint == null)
492         throw new IllegalArgumentException JavaDoc("connect: The address can't be null");
493
494     if (timeout < 0)
495       throw new IllegalArgumentException JavaDoc("connect: timeout can't be negative");
496
497     if (isClosed())
498         throw new SocketException JavaDoc("Socket is closed");
499
500     if (!oldImpl && isConnected())
501         throw new SocketException JavaDoc("already connected");
502
503     if (!(endpoint instanceof InetSocketAddress JavaDoc))
504         throw new IllegalArgumentException JavaDoc("Unsupported address type");
505
506     InetSocketAddress JavaDoc epoint = (InetSocketAddress JavaDoc) endpoint;
507
508     SecurityManager JavaDoc security = System.getSecurityManager();
509     if (security != null) {
510         if (epoint.isUnresolved())
511         security.checkConnect(epoint.getHostName(),
512                       epoint.getPort());
513         else
514         security.checkConnect(epoint.getAddress().getHostAddress(),
515                       epoint.getPort());
516     }
517     if (!created)
518         createImpl(true);
519     if (!oldImpl)
520         impl.connect(epoint, timeout);
521     else if (timeout == 0) {
522         if (epoint.isUnresolved())
523         impl.connect(epoint.getAddress().getHostName(),
524                  epoint.getPort());
525         else
526         impl.connect(epoint.getAddress(), epoint.getPort());
527     } else
528         throw new UnsupportedOperationException JavaDoc("SocketImpl.connect(addr, timeout)");
529     connected = true;
530     /*
531      * If the socket was not bound before the connect, it is now because
532      * the kernel will have picked an ephemeral port & a local address
533      */

534     bound = true;
535     }
536
537     /**
538      * Binds the socket to a local address.
539      * <P>
540      * If the address is <code>null</code>, then the system will pick up
541      * an ephemeral port and a valid local address to bind the socket.
542      *
543      * @param bindpoint the <code>SocketAddress</code> to bind to
544      * @throws IOException if the bind operation fails, or if the socket
545      * is already bound.
546      * @throws IllegalArgumentException if bindpoint is a
547      * SocketAddress subclass not supported by this socket
548      *
549      * @since 1.4
550      * @see #isBound
551      */

552     public void bind(SocketAddress JavaDoc bindpoint) throws IOException JavaDoc {
553     if (isClosed())
554         throw new SocketException JavaDoc("Socket is closed");
555     if (!oldImpl && isBound())
556         throw new SocketException JavaDoc("Already bound");
557
558     if (bindpoint != null && (!(bindpoint instanceof InetSocketAddress JavaDoc)))
559         throw new IllegalArgumentException JavaDoc("Unsupported address type");
560     InetSocketAddress JavaDoc epoint = (InetSocketAddress JavaDoc) bindpoint;
561     if (epoint != null && epoint.isUnresolved())
562         throw new SocketException JavaDoc("Unresolved address");
563     if (bindpoint == null)
564         getImpl().bind(InetAddress.anyLocalAddress(), 0);
565     else
566         getImpl().bind(epoint.getAddress(),
567                epoint.getPort());
568     bound = true;
569     }
570
571     /**
572      * set the flags after an accept() call.
573      */

574     final void postAccept() {
575     connected = true;
576     created = true;
577     bound = true;
578     }
579
580     void setCreated() {
581     created = true;
582     }
583
584     void setBound() {
585     bound = true;
586     }
587
588     void setConnected() {
589     connected = true;
590     }
591
592     /**
593      * Returns the address to which the socket is connected.
594      *
595      * @return the remote IP address to which this socket is connected,
596      * or <code>null</code> if the socket is not connected.
597      */

598     public InetAddress JavaDoc getInetAddress() {
599     if (!isConnected())
600         return null;
601     try {
602         return getImpl().getInetAddress();
603     } catch (SocketException JavaDoc e) {
604     }
605     return null;
606     }
607
608     /**
609      * Gets the local address to which the socket is bound.
610      *
611      * @return the local address to which the socket is bound or
612      * <code>InetAddress.anyLocalAddress()</code>
613      * if the socket is not bound yet.
614      * @since JDK1.1
615      */

616     public InetAddress JavaDoc getLocalAddress() {
617     // This is for backward compatibility
618
if (!isBound())
619         return InetAddress.anyLocalAddress();
620     InetAddress JavaDoc in = null;
621     try {
622         in = (InetAddress JavaDoc) getImpl().getOption(SocketOptions.SO_BINDADDR);
623         if (in.isAnyLocalAddress()) {
624         in = InetAddress.anyLocalAddress();
625         }
626     } catch (Exception JavaDoc e) {
627         in = InetAddress.anyLocalAddress(); // "0.0.0.0"
628
}
629     return in;
630     }
631
632     /**
633      * Returns the remote port to which this socket is connected.
634      *
635      * @return the remote port number to which this socket is connected, or
636      * 0 if the socket is not connected yet.
637      */

638     public int getPort() {
639     if (!isConnected())
640         return 0;
641     try {
642         return getImpl().getPort();
643     } catch (SocketException JavaDoc e) {
644         // Shouldn't happen as we're connected
645
}
646     return -1;
647     }
648
649     /**
650      * Returns the local port to which this socket is bound.
651      *
652      * @return the local port number to which this socket is bound or -1
653      * if the socket is not bound yet.
654      */

655     public int getLocalPort() {
656     if (!isBound())
657         return -1;
658     try {
659         return getImpl().getLocalPort();
660     } catch(SocketException JavaDoc e) {
661         // shouldn't happen as we're bound
662
}
663     return -1;
664     }
665
666     /**
667      * Returns the address of the endpoint this socket is connected to, or
668      * <code>null</code> if it is unconnected.
669      * @return a <code>SocketAddress</code> reprensenting the remote endpoint of this
670      * socket, or <code>null</code> if it is not connected yet.
671      * @see #getInetAddress()
672      * @see #getPort()
673      * @see #connect(SocketAddress, int)
674      * @see #connect(SocketAddress)
675      * @since 1.4
676      */

677     public SocketAddress JavaDoc getRemoteSocketAddress() {
678     if (!isConnected())
679         return null;
680     return new InetSocketAddress JavaDoc(getInetAddress(), getPort());
681     }
682
683     /**
684      * Returns the address of the endpoint this socket is bound to, or
685      * <code>null</code> if it is not bound yet.
686      *
687      * @return a <code>SocketAddress</code> representing the local endpoint of this
688      * socket, or <code>null</code> if it is not bound yet.
689      * @see #getLocalAddress()
690      * @see #getLocalPort()
691      * @see #bind(SocketAddress)
692      * @since 1.4
693      */

694
695     public SocketAddress JavaDoc getLocalSocketAddress() {
696     if (!isBound())
697         return null;
698     return new InetSocketAddress JavaDoc(getLocalAddress(), getLocalPort());
699     }
700
701     /**
702      * Returns the unique {@link java.nio.channels.SocketChannel SocketChannel}
703      * object associated with this socket, if any.
704      *
705      * <p> A socket will have a channel if, and only if, the channel itself was
706      * created via the {@link java.nio.channels.SocketChannel#open
707      * SocketChannel.open} or {@link
708      * java.nio.channels.ServerSocketChannel#accept ServerSocketChannel.accept}
709      * methods.
710      *
711      * @return the socket channel associated with this socket,
712      * or <tt>null</tt> if this socket was not created
713      * for a channel
714      *
715      * @since 1.4
716      * @spec JSR-51
717      */

718     public SocketChannel JavaDoc getChannel() {
719     return null;
720     }
721
722     /**
723      * Returns an input stream for this socket.
724      *
725      * <p> If this socket has an associated channel then the resulting input
726      * stream delegates all of its operations to the channel. If the channel
727      * is in non-blocking mode then the input stream's <tt>read</tt> operations
728      * will throw an {@link java.nio.channels.IllegalBlockingModeException}.
729      *
730      * <p>Under abnormal conditions the underlying connection may be
731      * broken by the remote host or the network software (for example
732      * a connection reset in the case of TCP connections). When a
733      * broken connection is detected by the network software the
734      * following applies to the returned input stream :-
735      *
736      * <ul>
737      *
738      * <li><p>The network software may discard bytes that are buffered
739      * by the socket. Bytes that aren't discarded by the network
740      * software can be read using {@link java.io.InputStream#read read}.
741      *
742      * <li><p>If there are no bytes buffered on the socket, or all
743      * buffered bytes have been consumed by
744      * {@link java.io.InputStream#read read}, then all subsequent
745      * calls to {@link java.io.InputStream#read read} will throw an
746      * {@link java.io.IOException IOException}.
747      *
748      * <li><p>If there are no bytes buffered on the socket, and the
749      * socket has not been closed using {@link #close close}, then
750      * {@link java.io.InputStream#available available} will
751      * return <code>0</code>.
752      *
753      * </ul>
754      *
755      * @return an input stream for reading bytes from this socket.
756      * @exception IOException if an I/O error occurs when creating the
757      * input stream, the socket is closed, the socket is
758      * not connected, or the socket input has been shutdown
759      * using {@link #shutdownInput()}
760      *
761      * @revised 1.4
762      * @spec JSR-51
763      */

764     public InputStream JavaDoc getInputStream() throws IOException JavaDoc {
765     if (isClosed())
766         throw new SocketException JavaDoc("Socket is closed");
767     if (!isConnected())
768         throw new SocketException JavaDoc("Socket is not connected");
769     if (isInputShutdown())
770         throw new SocketException JavaDoc("Socket input is shutdown");
771     final Socket JavaDoc s = this;
772     InputStream JavaDoc is = null;
773     try {
774         is = (InputStream JavaDoc)
775         AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc() {
776             public Object JavaDoc run() throws IOException JavaDoc {
777             return impl.getInputStream();
778             }
779         });
780     } catch (java.security.PrivilegedActionException JavaDoc e) {
781         throw (IOException JavaDoc) e.getException();
782     }
783     return is;
784     }
785
786     /**
787      * Returns an output stream for this socket.
788      *
789      * <p> If this socket has an associated channel then the resulting output
790      * stream delegates all of its operations to the channel. If the channel
791      * is in non-blocking mode then the output stream's <tt>write</tt>
792      * operations will throw an {@link
793      * java.nio.channels.IllegalBlockingModeException}.
794      *
795      * @return an output stream for writing bytes to this socket.
796      * @exception IOException if an I/O error occurs when creating the
797      * output stream or if the socket is not connected.
798      * @revised 1.4
799      * @spec JSR-51
800      */

801     public OutputStream JavaDoc getOutputStream() throws IOException JavaDoc {
802     if (isClosed())
803         throw new SocketException JavaDoc("Socket is closed");
804     if (!isConnected())
805         throw new SocketException JavaDoc("Socket is not connected");
806     if (isOutputShutdown())
807         throw new SocketException JavaDoc("Socket output is shutdown");
808     final Socket JavaDoc s = this;
809     OutputStream JavaDoc os = null;
810     try {
811         os = (OutputStream JavaDoc)
812         AccessController.doPrivileged(new PrivilegedExceptionAction JavaDoc() {
813             public Object JavaDoc run() throws IOException JavaDoc {
814             return impl.getOutputStream();
815             }
816         });
817     } catch (java.security.PrivilegedActionException JavaDoc e) {
818         throw (IOException JavaDoc) e.getException();
819     }
820     return os;
821     }
822
823     /**
824      * Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).
825      *
826      * @param on <code>true</code> to enable TCP_NODELAY,
827      * <code>false</code> to disable.
828      *
829      * @exception SocketException if there is an error
830      * in the underlying protocol, such as a TCP error.
831      *
832      * @since JDK1.1
833      *
834      * @see #getTcpNoDelay()
835      */

836     public void setTcpNoDelay(boolean on) throws SocketException JavaDoc {
837     if (isClosed())
838         throw new SocketException JavaDoc("Socket is closed");
839     getImpl().setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
840     }
841
842     /**
843      * Tests if TCP_NODELAY is enabled.
844      *
845      * @return a <code>boolean</code> indicating whether or not TCP_NODELAY is enabled.
846      * @exception SocketException if there is an error
847      * in the underlying protocol, such as a TCP error.
848      * @since JDK1.1
849      * @see #setTcpNoDelay(boolean)
850      */

851     public boolean getTcpNoDelay() throws SocketException JavaDoc {
852     if (isClosed())
853         throw new SocketException JavaDoc("Socket is closed");
854     return ((Boolean JavaDoc) getImpl().getOption(SocketOptions.TCP_NODELAY)).booleanValue();
855     }
856
857     /**
858      * Enable/disable SO_LINGER with the specified linger time in seconds.
859      * The maximum timeout value is platform specific.
860      *
861      * The setting only affects socket close.
862      *
863      * @param on whether or not to linger on.
864      * @param linger how long to linger for, if on is true.
865      * @exception SocketException if there is an error
866      * in the underlying protocol, such as a TCP error.
867      * @exception IllegalArgumentException if the linger value is negative.
868      * @since JDK1.1
869      * @see #getSoLinger()
87