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()
870      */

871     public void setSoLinger(boolean on, int linger) throws SocketException JavaDoc {
872     if (isClosed())
873         throw new SocketException JavaDoc("Socket is closed");
874     if (!on) {
875         getImpl().setOption(SocketOptions.SO_LINGER, new Boolean JavaDoc(on));
876     } else {
877         if (linger < 0) {
878         throw new IllegalArgumentException JavaDoc("invalid value for SO_LINGER");
879         }
880             if (linger > 65535)
881                 linger = 65535;
882         getImpl().setOption(SocketOptions.SO_LINGER, new Integer JavaDoc(linger));
883     }
884     }
885
886     /**
887      * Returns setting for SO_LINGER. -1 returns implies that the
888      * option is disabled.
889      *
890      * The setting only affects socket close.
891      *
892      * @return the setting for SO_LINGER.
893      * @exception SocketException if there is an error
894      * in the underlying protocol, such as a TCP error.
895      * @since JDK1.1
896      * @see #setSoLinger(boolean, int)
897      */

898     public int getSoLinger() throws SocketException JavaDoc {
899     if (isClosed())
900         throw new SocketException JavaDoc("Socket is closed");
901     Object JavaDoc o = getImpl().getOption(SocketOptions.SO_LINGER);
902     if (o instanceof Integer JavaDoc) {
903         return ((Integer JavaDoc) o).intValue();
904     } else {
905         return -1;
906     }
907     }
908
909     /**
910      * Send one byte of urgent data on the socket. The byte to be sent is the lowest eight
911      * bits of the data parameter. The urgent byte is
912      * sent after any preceding writes to the socket OutputStream
913      * and before any future writes to the OutputStream.
914      * @param data The byte of data to send
915      * @exception IOException if there is an error
916      * sending the data.
917      * @since 1.4
918      */

919     public void sendUrgentData (int data) throws IOException JavaDoc {
920         if (!getImpl().supportsUrgentData ()) {
921             throw new SocketException JavaDoc ("Urgent data not supported");
922         }
923         getImpl().sendUrgentData (data);
924     }
925
926     /**
927      * Enable/disable OOBINLINE (receipt of TCP urgent data)
928      *
929      * By default, this option is disabled and TCP urgent data received on a
930      * socket is silently discarded. If the user wishes to receive urgent data, then
931      * this option must be enabled. When enabled, urgent data is received
932      * inline with normal data.
933      * <p>
934      * Note, only limited support is provided for handling incoming urgent
935      * data. In particular, no notification of incoming urgent data is provided
936      * and there is no capability to distinguish between normal data and urgent
937      * data unless provided by a higher level protocol.
938      *
939      * @param on <code>true</code> to enable OOBINLINE,
940      * <code>false</code> to disable.
941      *
942      * @exception SocketException if there is an error
943      * in the underlying protocol, such as a TCP error.
944      *
945      * @since 1.4
946      *
947      * @see #getOOBInline()
948      */

949     public void setOOBInline(boolean on) throws SocketException JavaDoc {
950     if (isClosed())
951         throw new SocketException JavaDoc("Socket is closed");
952     getImpl().setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(on));
953     }
954
955     /**
956      * Tests if OOBINLINE is enabled.
957      *
958      * @return a <code>boolean</code> indicating whether or not OOBINLINE is enabled.
959      * @exception SocketException if there is an error
960      * in the underlying protocol, such as a TCP error.
961      * @since 1.4
962      * @see #setOOBInline(boolean)
963      */

964     public boolean getOOBInline() throws SocketException JavaDoc {
965     if (isClosed())
966         throw new SocketException JavaDoc("Socket is closed");
967     return ((Boolean JavaDoc) getImpl().getOption(SocketOptions.SO_OOBINLINE)).booleanValue();
968     }
969
970     /**
971      * Enable/disable SO_TIMEOUT with the specified timeout, in
972      * milliseconds. With this option set to a non-zero timeout,
973      * a read() call on the InputStream associated with this Socket
974      * will block for only this amount of time. If the timeout expires,
975      * a <B>java.net.SocketTimeoutException</B> is raised, though the
976      * Socket is still valid. The option <B>must</B> be enabled
977      * prior to entering the blocking operation to have effect. The
978      * timeout must be > 0.
979      * A timeout of zero is interpreted as an infinite timeout.
980      * @param timeout the specified timeout, in milliseconds.
981      * @exception SocketException if there is an error
982      * in the underlying protocol, such as a TCP error.
983      * @since JDK 1.1
984      * @see #getSoTimeout()
985      */

986     public synchronized void setSoTimeout(int timeout) throws SocketException JavaDoc {
987     if (isClosed())
988         throw new SocketException JavaDoc("Socket is closed");
989     if (timeout < 0)
990       throw new IllegalArgumentException JavaDoc("timeout can't be negative");
991
992     getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer JavaDoc(timeout));
993     }
994
995     /**
996      * Returns setting for SO_TIMEOUT. 0 returns implies that the
997      * option is disabled (i.e., timeout of infinity).
998      * @return the setting for SO_TIMEOUT
999      * @exception SocketException if there is an error
1000     * in the underlying protocol, such as a TCP error.
1001     * @since JDK1.1
1002     * @see #setSoTimeout(int)
1003     */

1004    public synchronized int getSoTimeout() throws SocketException JavaDoc {
1005    if (isClosed())
1006        throw new SocketException JavaDoc("Socket is closed");
1007    Object JavaDoc o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
1008    /* extra type safety */
1009    if (o instanceof Integer JavaDoc) {
1010        return ((Integer JavaDoc) o).intValue();
1011    } else {
1012        return 0;
1013    }
1014    }
1015
1016    /**
1017     * Sets the SO_SNDBUF option to the specified value for this
1018     * <tt>Socket</tt>. The SO_SNDBUF option is used by the platform's
1019     * networking code as a hint for the size to set
1020     * the underlying network I/O buffers.
1021     *
1022     * <p>Because SO_SNDBUF is a hint, applications that want to
1023     * verify what size the buffers were set to should call
1024     * {@link #getSendBufferSize()}.
1025     *
1026     * @exception SocketException if there is an error
1027     * in the underlying protocol, such as a TCP error.
1028     *
1029     * @param size the size to which to set the send buffer
1030     * size. This value must be greater than 0.
1031     *
1032     * @exception IllegalArgumentException if the
1033     * value is 0 or is negative.
1034     *
1035     * @see #getSendBufferSize()
1036     * @since 1.2
1037     */

1038    public synchronized void setSendBufferSize(int size)
1039    throws SocketException JavaDoc{
1040    if (!(size > 0)) {
1041        throw new IllegalArgumentException JavaDoc("negative send size");
1042    }
1043    if (isClosed())
1044        throw new SocketException JavaDoc("Socket is closed");
1045    getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer JavaDoc(size));
1046    }
1047
1048    /**
1049     * Get value of the SO_SNDBUF option for this <tt>Socket</tt>,
1050     * that is the buffer size used by the platform
1051     * for output on this <tt>Socket</tt>.
1052     * @return the value of the SO_SNDBUF option for this <tt>Socket</tt>.
1053     *
1054     * @exception SocketException if there is an error
1055     * in the underlying protocol, such as a TCP error.
1056     *
1057     * @see #setSendBufferSize(int)
1058     * @since 1.2
1059     */

1060    public synchronized int getSendBufferSize() throws SocketException JavaDoc {
1061    if (isClosed())
1062        throw new SocketException JavaDoc("Socket is closed");
1063    int result = 0;
1064    Object JavaDoc o = getImpl().getOption(SocketOptions.SO_SNDBUF);
1065    if (o instanceof Integer JavaDoc) {
1066        result = ((Integer JavaDoc)o).intValue();
1067    }
1068    return result;
1069    }
1070
1071    /**
1072     * Sets the SO_RCVBUF option to the specified value for this
1073     * <tt>Socket</tt>. The SO_RCVBUF option is used by the platform's
1074     * networking code as a hint for the size to set
1075     * the underlying network I/O buffers.
1076     *
1077     * <p>Increasing the receive buffer size can increase the performance of
1078     * network I/O for high-volume connection, while decreasing it can
1079     * help reduce the backlog of incoming data.
1080     *
1081     * <p>Because SO_RCVBUF is a hint, applications that want to
1082     * verify what size the buffers were set to should call
1083     * {@link #getReceiveBufferSize()}.
1084     *
1085     * <p>The value of SO_RCVBUF is also used to set the TCP receive window
1086     * that is advertized to the remote peer. Generally, the window size
1087     * can be modified at any time when a socket is connected. However, if
1088     * a receive window larger than 64K is required then this must be requested
1089     * <B>before</B> the socket is connected to the remote peer. There are two
1090     * cases to be aware of:<p>
1091     * <ol>
1092     * <li>For sockets accepted from a ServerSocket, this must be done by calling
1093     * {@link ServerSocket#setReceiveBufferSize(int)} before the ServerSocket
1094     * is bound to a local address.<p></li>
1095     * <li>For client sockets, setReceiveBufferSize() must be called before
1096     * connecting the socket to its remote peer.<p></li></ol>
1097     * @param size the size to which to set the receive buffer
1098     * size. This value must be greater than 0.
1099     *
1100     * @exception IllegalArgumentException if the value is 0 or is
1101     * negative.
1102     *
1103     * @exception SocketException if there is an error
1104     * in the underlying protocol, such as a TCP error.
1105     *
1106     * @see #getReceiveBufferSize()
1107     * @see ServerSocket#setReceiveBufferSize(int)
1108     * @since 1.2
1109     */

1110    public synchronized void setReceiveBufferSize(int size)
1111    throws SocketException JavaDoc{
1112    if (size <= 0) {
1113        throw new IllegalArgumentException JavaDoc("invalid receive size");
1114    }
1115    if (isClosed())
1116        throw new SocketException JavaDoc("Socket is closed");
1117    getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer JavaDoc(size));
1118    }
1119
1120    /**
1121     * Gets the value of the SO_RCVBUF option for this <tt>Socket</tt>,
1122     * that is the buffer size used by the platform for
1123     * input on this <tt>Socket</tt>.
1124     *
1125     * @return the value of the SO_RCVBUF option for this <tt>Socket</tt>.
1126     * @exception SocketException if there is an error
1127     * in the underlying protocol, such as a TCP error.
1128     * @see #setReceiveBufferSize(int)
1129     * @since 1.2
1130     */

1131    public synchronized int getReceiveBufferSize()
1132    throws SocketException JavaDoc{
1133    if (isClosed())
1134        throw new SocketException JavaDoc("Socket is closed");
1135    int result = 0;
1136    Object JavaDoc o = getImpl().getOption(SocketOptions.SO_RCVBUF);
1137    if (o instanceof Integer JavaDoc) {
1138        result = ((Integer JavaDoc)o).intValue();
1139    }
1140    return result;
1141    }
1142
1143    /**
1144     * Enable/disable SO_KEEPALIVE.
1145     *
1146     * @param on whether or not to have socket keep alive turned on.
1147     * @exception SocketException if there is an error
1148     * in the underlying protocol, such as a TCP error.
1149     * @since 1.3
1150     * @see #getKeepAlive()
1151     */

1152    public void setKeepAlive(boolean on) throws SocketException JavaDoc {
1153    if (isClosed())
1154        throw new SocketException JavaDoc("Socket is closed");
1155        getImpl().setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(on));
1156    }
1157
1158    /**
1159     * Tests if SO_KEEPALIVE is enabled.
1160     *
1161     * @return a <code>boolean</code> indicating whether or not SO_KEEPALIVE is enabled.
1162     * @exception SocketException if there is an error
1163     * in the underlying protocol, such as a TCP error.
1164     * @since 1.3
1165     * @see #setKeepAlive(boolean)
1166     */

1167    public boolean getKeepAlive() throws SocketException JavaDoc {
1168    if (isClosed())
1169        throw new SocketException JavaDoc("Socket is closed");
1170    return ((Boolean JavaDoc) getImpl().getOption(SocketOptions.SO_KEEPALIVE)).booleanValue();
1171    }
1172
1173    /**
1174     * Sets traffic class or type-of-service octet in the IP
1175     * header for packets sent from this Socket.
1176     * As the underlying network implementation may ignore this
1177     * value applications should consider it a hint.
1178     *
1179     * <P> The tc <B>must</B> be in the range <code> 0 <= tc <=
1180     * 255</code> or an IllegalArgumentException will be thrown.
1181     * <p>Notes:
1182     * <p> for Internet Protocol v4 the value consists of an octet
1183     * with precedence and TOS fields as detailed in RFC 1349. The
1184     * TOS field is bitset created by bitwise-or'ing values such
1185     * the following :-
1186     * <p>
1187     * <UL>
1188     * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
1189     * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
1190     * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
1191     * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
1192     * </UL>
1193     * The last low order bit is always ignored as this
1194     * corresponds to the MBZ (must be zero) bit.
1195     * <p>
1196     * Setting bits in the precedence field may result in a
1197     * SocketException indicating that the operation is not
1198     * permitted.
1199     * <p>
1200     * for Internet Protocol v6 <code>tc</code> is the value that
1201     * would be placed into the sin6_flowinfo field of the IP header.
1202     *
1203     * @param tc an <code>int</code> value for the bitset.
1204     * @throws SocketException if there is an error setting the
1205     * traffic class or type-of-service
1206     * @since 1.4
1207     * @see #getTrafficClass
1208     */

1209    public void setTrafficClass(int tc) throws SocketException JavaDoc {
1210    if (tc < 0 || tc > 255)
1211        throw new IllegalArgumentException JavaDoc("tc is not in range 0 -- 255");
1212
1213    if (isClosed())
1214        throw new SocketException JavaDoc("Socket is closed");
1215        getImpl().setOption(SocketOptions.IP_TOS, new Integer JavaDoc(tc));
1216    }
1217
1218    /**
1219     * Gets traffic class or type-of-service in the IP header
1220     * for packets sent from this Socket
1221     * <p>
1222     * As the underlying network implementation may ignore the
1223     * traffic class or type-of-service set using {@link #setTrafficClass(int)}
1224     * this method may return a different value than was previously
1225     * set using the {@link #setTrafficClass(int)} method on this Socket.
1226     *
1227     * @return the traffic class or type-of-service already set
1228     * @throws SocketException if there is an error obtaining the
1229     * traffic class or type-of-service value.
1230     * @since 1.4
1231     * @see #setTrafficClass(int)
1232     */

1233    public int getTrafficClass() throws SocketException JavaDoc {
1234        return ((Integer JavaDoc) (getImpl().getOption(SocketOptions.IP_TOS))).intValue();
1235    }
1236
1237    /**
1238     * Enable/disable the SO_REUSEADDR socket option.
1239     * <p>
1240     * When a TCP connection is closed the connection may remain
1241     * in a timeout state for a period of time after the connection
1242     * is closed (typically known as the <tt>TIME_WAIT</tt> state
1243     * or <tt>2MSL</tt> wait state).
1244     * For applications using a well known socket address or port
1245     * it may not be possible to bind a socket to the required
1246     * <tt>SocketAddress</tt> if there is a connection in the
1247     * timeout state involving the socket address or port.
1248     * <p>
1249     * Enabling <tt>SO_REUSEADDR</tt> prior to binding the socket
1250     * using {@link #bind(SocketAddress)} allows the socket to be
1251     * bound even though a previous connection is in a timeout
1252     * state.
1253     * <p>
1254     * When a <tt>Socket</tt> is created the initial setting
1255     * of <tt>SO_REUSEADDR</tt> is disabled.
1256     * <p>
1257     * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
1258     * disabled after a socket is bound (See {@link #isBound()})
1259     * is not defined.
1260     *
1261     * @param on whether to enable or disable the socket option
1262     * @exception SocketException if an error occurs enabling or
1263     * disabling the <tt>SO_RESUEADDR</tt> socket option,
1264     * or the socket is closed.
1265     * @since 1.4
1266     * @see #getReuseAddress()
1267     * @see #bind(SocketAddress)
1268     * @see #isClosed()
1269     * @see #isBound()
1270     */

1271    public void setReuseAddress(boolean on) throws SocketException JavaDoc {
1272    if (isClosed())
1273        throw new SocketException JavaDoc("Socket is closed");
1274        getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
1275    }
1276
1277    /**
1278     * Tests if SO_REUSEADDR is enabled.
1279     *
1280     * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
1281     * @exception SocketException if there is an error
1282     * in the underlying protocol, such as a TCP error.
1283     * @since 1.4
1284     * @see #setReuseAddress(boolean)
1285     */

1286    public boolean getReuseAddress() throws SocketException JavaDoc {
1287    if (isClosed())
1288        throw new SocketException JavaDoc("Socket is closed");
1289    return ((Boolean JavaDoc) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
1290    }
1291
1292    /**
1293     * Closes this socket.
1294     * <p>
1295     * Any thread currently blocked in an I/O operation upon this socket
1296     * will throw a {@link SocketException}.
1297     * <p>
1298     * Once a socket has been closed, it is not available for further networking
1299     * use (i.e. can't be reconnected or rebound). A new socket needs to be
1300     * created.
1301     *
1302     * <p> If this socket has an associated channel then the channel is closed
1303     * as well.
1304     *
1305     * @exception IOException if an I/O error occurs when closing this socket.
1306     * @revised 1.4
1307     * @spec JSR-51
1308     * @see #isClosed
1309     */

1310    public synchronized void close() throws IOException JavaDoc {
1311    synchronized(closeLock) {
1312        if (isClosed())
1313        return;
1314        if (created)
1315        impl.close();
1316        closed = true;
1317    }
1318    }
1319
1320    /**
1321     * Places the input stream for this socket at "end of stream".
1322     * Any data sent to the input stream side of the socket is acknowledged
1323     * and then silently discarded.
1324     * <p>
1325     * If you read from a socket input stream after invoking
1326     * shutdownInput() on the socket, the stream will return EOF.
1327     *
1328     * @exception IOException if an I/O error occurs when shutting down this
1329     * socket.
1330     *
1331     * @since 1.3
1332     * @see java.net.Socket#shutdownOutput()
1333     * @see java.net.Socket#close()
1334     * @see java.net.Socket#setSoLinger(boolean, int)
1335     * @see #isInputShutdown
1336     */

1337    public void shutdownInput() throws IOException JavaDoc
1338    {
1339    if (isClosed())
1340        throw new SocketException JavaDoc("Socket is closed");
1341    if (!isConnected())
1342        throw new SocketException JavaDoc("Socket is not connected");
1343    if (isInputShutdown())
1344        throw new SocketException JavaDoc("Socket input is already shutdown");
1345    getImpl().shutdownInput();
1346    shutIn = true;
1347    }
1348    
1349    /**
1350     * Disables the output stream for this socket.
1351     * For a TCP socket, any previously written data will be sent
1352     * followed by TCP's normal connection termination sequence.
1353     *
1354     * If you write to a socket output stream after invoking
1355     * shutdownOutput() on the socket, the stream will throw
1356     * an IOException.
1357     *
1358     * @exception IOException if an I/O error occurs when shutting down this
1359     * socket.
1360     *
1361     * @since 1.3
1362     * @see java.net.Socket#shutdownInput()
1363     * @see java.net.Socket#close()
1364     * @see java.net.Socket#setSoLinger(boolean, int)
1365     * @see #isOutputShutdown
1366     */

1367    public void shutdownOutput() throws IOException JavaDoc
1368    {
1369    if (isClosed())
1370        throw new SocketException JavaDoc("Socket is closed");
1371    if (!isConnected())
1372        throw new SocketException JavaDoc("Socket is not connected");
1373    if (isOutputShutdown())
1374        throw new SocketException JavaDoc("Socket output is already shutdown");
1375    getImpl().shutdownOutput();
1376    shutOut = true;
1377    }
1378
1379    /**
1380     * Converts this socket to a <code>String</code>.
1381     *
1382     * @return a string representation of this socket.
1383     */

1384    public String JavaDoc toString() {
1385    try {
1386        if (isConnected())
1387        return "Socket[addr=" + getImpl().getInetAddress() +
1388            ",port=" + getImpl().getPort() +
1389            ",localport=" + getImpl().getLocalPort() + "]";
1390    } catch (SocketException JavaDoc e) {
1391    }
1392    return "Socket[unconnected]";
1393    }
1394
1395    /**
1396     * Returns the connection state of the socket.
1397     *
1398     * @return true if the socket successfuly connected to a server
1399     * @since 1.4
1400     */

1401    public boolean isConnected() {
1402    // Before 1.3 Sockets were always connected during creation
1403
return connected || oldImpl;
1404    }
1405
1406    /**
1407     * Returns the binding state of the socket.
1408     *
1409     * @return true if the socket successfuly bound to an address
1410     * @since 1.4
1411     * @see #bind
1412     */

1413    public boolean isBound() {
1414    // Before 1.3 Sockets were always bound during creation
1415
return bound || oldImpl;
1416    }
1417
1418    /**
1419     * Returns the closed state of the socket.
1420     *
1421     * @return true if the socket has been closed
1422     * @since 1.4
1423     * @see #close
1424     */

1425    public boolean isClosed() {
1426    synchronized(closeLock) {
1427        return closed;
1428    }
1429    }
1430
1431    /**
1432     * Returns whether the read-half of the socket connection is closed.
1433     *
1434     * @return true if the input of the socket has been shutdown
1435     * @since 1.4
1436     * @see #shutdownInput
1437     */

1438    public boolean isInputShutdown() {
1439    return shutIn;
1440    }
1441
1442    /**
1443     * Returns whether the write-half of the socket connection is closed.
1444     *
1445     * @return true if the output of the socket has been shutdown
1446     * @since 1.4
1447     * @see #shutdownOutput
1448     */

1449    public boolean isOutputShutdown() {
1450    return shutOut;
1451    }
1452
1453    /**
1454     * The factory for all client sockets.
1455     */

1456    private static SocketImplFactory JavaDoc factory = null;
1457
1458    /**
1459     * Sets the client socket implementation factory for the
1460     * application. The factory can be specified only once.
1461     * <p>
1462     * When an application creates a new client socket, the socket
1463     * implementation factory's <code>createSocketImpl</code> method is
1464     * called to create the actual socket implementation.
1465     * <p>
1466     * Passing <code>null</code> to the method is a no-op unless the factory
1467     * was already set.
1468     * <p>If there is a security manager, this method first calls
1469     * the security manager's <code>checkSetFactory</code> method
1470     * to ensure the operation is allowed.
1471     * This could result in a SecurityException.
1472     *
1473     * @param fac the desired factory.
1474     * @exception IOException if an I/O error occurs when setting the
1475     * socket factory.
1476     * @exception SocketException if the factory is already defined.
1477     * @exception SecurityException if a security manager exists and its
1478     * <code>checkSetFactory</code> method doesn't allow the operation.
1479     * @see java.net.SocketImplFactory#createSocketImpl()
1480     * @see SecurityManager#checkSetFactory
1481     */

1482    public static synchronized void setSocketImplFactory(SocketImplFactory JavaDoc fac)
1483    throws IOException JavaDoc
1484    {
1485    if (factory != null) {
1486        throw new SocketException JavaDoc("factory already defined");
1487    }
1488    SecurityManager JavaDoc security = System.getSecurityManager();
1489    if (security != null) {
1490        security.checkSetFactory();
1491    }
1492    factory = fac;
1493    }
1494
1495    /**
1496     * Sets performance preferences for this socket.
1497     *
1498     * <p> Sockets use the TCP/IP protocol by default. Some implementations
1499     * may offer alternative protocols which have different performance
1500     * characteristics than TCP/IP. This method allows the application to
1501     * express its own preferences as to how these tradeoffs should be made
1502     * when the implementation chooses from the available protocols.
1503     *
1504     * <p> Performance preferences are described by three integers
1505     * whose values indicate the relative importance of short connection time,
1506     * low latency, and high bandwidth. The absolute values of the integers
1507     * are irrelevant; in order to choose a protocol the values are simply
1508     * compared, with larger values indicating stronger preferences. Negative
1509     * values represent a lower priority than positive values. If the
1510     * application prefers short connection time over both low latency and high
1511     * bandwidth, for example, then it could invoke this method with the values
1512     * <tt>(1, 0, 0)</tt>. If the application prefers high bandwidth above low
1513     * latency, and low latency above short connection time, then it could
1514     * invoke this method with the values <tt>(0, 1, 2)</tt>.
1515     *
1516     * <p> Invoking this method after this socket has been connected
1517     * will have no effect.
1518     *
1519     * @param connectionTime
1520     * An <tt>int</tt> expressing the relative importance of a short
1521     * connection time
1522     *
1523     * @param latency
1524     * An <tt>int</tt> expressing the relative importance of low
1525     * latency
1526     *
1527     * @param bandwidth
1528     * An <tt>int</tt> expressing the relative importance of high
1529     * bandwidth
1530     *
1531     * @since 1.5
1532     */

1533    public void setPerformancePreferences(int connectionTime,
1534                                          int latency,
1535                                          int bandwidth)
1536    {
1537    /* Not implemented yet */
1538    }
1539}
1540
Popular Tags