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