1 /*
   2  * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.net;
  27 
  28 import java.io.IOException;
  29 import java.io.UncheckedIOException;
  30 import java.nio.channels.DatagramChannel;
  31 import java.security.AccessController;
  32 import java.security.PrivilegedExceptionAction;
  33 import java.util.Objects;
  34 import java.util.Set;
  35 import java.util.Collections;
  36 
  37 /**
  38  * This class represents a socket for sending and receiving datagram packets.
  39  *
  40  * <p>A datagram socket is the sending or receiving point for a packet
  41  * delivery service. Each packet sent or received on a datagram socket
  42  * is individually addressed and routed. Multiple packets sent from
  43  * one machine to another may be routed differently, and may arrive in
  44  * any order.
  45  *
  46  * <p> Where possible, a newly constructed {@code DatagramSocket} has the
  47  * {@link StandardSocketOptions#SO_BROADCAST SO_BROADCAST} socket option enabled so as
  48  * to allow the transmission of broadcast datagrams. In order to receive
  49  * broadcast packets a DatagramSocket should be bound to the wildcard address.
  50  * In some implementations, broadcast packets may also be received when
  51  * a DatagramSocket is bound to a more specific address.
  52  * <p>
  53  * Example:
  54  * <pre>{@code
  55  *              DatagramSocket s = new DatagramSocket(null);
  56  *              s.bind(new InetSocketAddress(8888));
  57  * }</pre>
  58  * Which is equivalent to:
  59  * <pre>{@code
  60  *              DatagramSocket s = new DatagramSocket(8888);
  61  * }</pre>
  62  * Both cases will create a DatagramSocket able to receive broadcasts on
  63  * UDP port 8888.
  64  *
  65  * <p> The {@code DatagramSocket} class defines convenience
  66  * methods to set and get several socket options. This class also
  67  * defines the {@link #setOption(SocketOption,Object) setOption}
  68  * and {@link #getOption(SocketOption) getOption} methods to set
  69  * and query socket options.
  70  * A {@code DatagramSocket} supports the following socket options:
  71  * <blockquote>
  72  * <a id="SocketOptions"></a>
  73  * <table class="striped">
  74  * <caption style="display:none">Socket options</caption>
  75  * <thead>
  76  *   <tr>
  77  *     <th scope="col">Option Name</th>
  78  *     <th scope="col">Description</th>
  79  *   </tr>
  80  * </thead>
  81  * <tbody>
  82  *   <tr>
  83  *     <th scope="row"> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </th>
  84  *     <td> The size of the socket send buffer </td>
  85  *   </tr>
  86  *   <tr>
  87  *     <th scope="row"> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </th>
  88  *     <td> The size of the socket receive buffer </td>
  89  *   </tr>
  90  *   <tr>
  91  *     <th scope="row"> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </th>
  92  *     <td> Re-use address </td>
  93  *   </tr>
  94  *   <tr>
  95  *     <th scope="row"> {@link java.net.StandardSocketOptions#SO_BROADCAST SO_BROADCAST} </th>
  96  *     <td> Allow transmission of broadcast datagrams </td>
  97  *   </tr>
  98  *   <tr>
  99  *     <th scope="row"> {@link java.net.StandardSocketOptions#IP_TOS IP_TOS} </th>
 100  *     <td> The Type of Service (ToS) octet in the Internet Protocol (IP) header </td>
 101  *   </tr>
 102  * </tbody>
 103  * </table>
 104  * </blockquote>
 105  * An implementation may also support additional options. In particular an implementation
 106  * may support <a href="MulticastSocket.html#MulticastOptions">multicast options</a> which
 107  * can be useful when using a plain {@code DatagramSocket} to send datagrams to a
 108  * multicast group.
 109  *
 110  * @author  Pavani Diwanji
 111  * @see     java.net.DatagramPacket
 112  * @see     java.nio.channels.DatagramChannel
 113  * @since 1.0
 114  */
 115 public class DatagramSocket implements java.io.Closeable {
 116     /**
 117      * Various states of this socket.
 118      */
 119     private boolean created = false;
 120     private boolean bound = false;
 121     private boolean closed = false;
 122     private Object closeLock = new Object();
 123 
 124     /*
 125      * The implementation of this DatagramSocket.
 126      */
 127     DatagramSocketImpl impl;
 128 
 129     /**
 130      * Are we using an older DatagramSocketImpl?
 131      */
 132     boolean oldImpl = false;
 133 
 134     /**
 135      * Set when a socket is ST_CONNECTED until we are certain
 136      * that any packets which might have been received prior
 137      * to calling connect() but not read by the application
 138      * have been read. During this time we check the source
 139      * address of all packets received to be sure they are from
 140      * the connected destination. Other packets are read but
 141      * silently dropped.
 142      */
 143     private boolean explicitFilter = false;
 144     private int bytesLeftToFilter;
 145     /*
 146      * Connection state:
 147      * ST_NOT_CONNECTED = socket not connected
 148      * ST_CONNECTED = socket connected
 149      * ST_CONNECTED_NO_IMPL = socket connected but not at impl level
 150      */
 151     static final int ST_NOT_CONNECTED = 0;
 152     static final int ST_CONNECTED = 1;
 153     static final int ST_CONNECTED_NO_IMPL = 2;
 154 
 155     int connectState = ST_NOT_CONNECTED;
 156 
 157     /*
 158      * Connected address & port
 159      */
 160     InetAddress connectedAddress = null;
 161     int connectedPort = -1;
 162 
 163     /**
 164      * Connects this socket to a remote socket address (IP address + port number).
 165      * Binds socket if not already bound.
 166      *
 167      * @param   address The remote address.
 168      * @param   port    The remote port
 169      * @throws  SocketException if binding the socket fails.
 170      */
 171     private synchronized void connectInternal(InetAddress address, int port) throws SocketException {
 172         if (port < 0 || port > 0xFFFF) {
 173             throw new IllegalArgumentException("connect: " + port);
 174         }
 175         if (address == null) {
 176             throw new IllegalArgumentException("connect: null address");
 177         }
 178         checkAddress (address, "connect");
 179         if (isClosed())
 180             return;
 181         SecurityManager security = System.getSecurityManager();
 182         if (security != null) {
 183             if (address.isMulticastAddress()) {
 184                 security.checkMulticast(address);
 185             } else {
 186                 security.checkConnect(address.getHostAddress(), port);
 187                 security.checkAccept(address.getHostAddress(), port);
 188             }
 189         }
 190 
 191         if (!isBound())
 192           bind(new InetSocketAddress(0));
 193 
 194         // old impls do not support connect/disconnect
 195         if (oldImpl || (impl instanceof AbstractPlainDatagramSocketImpl &&
 196              ((AbstractPlainDatagramSocketImpl)impl).nativeConnectDisabled())) {
 197             connectState = ST_CONNECTED_NO_IMPL;
 198         } else {
 199             try {
 200                 getImpl().connect(address, port);
 201 
 202                 // socket is now connected by the impl
 203                 connectState = ST_CONNECTED;
 204                 // Do we need to filter some packets?
 205                 int avail = getImpl().dataAvailable();
 206                 if (avail == -1) {
 207                     throw new SocketException();
 208                 }
 209                 explicitFilter = avail > 0;
 210                 if (explicitFilter) {
 211                     bytesLeftToFilter = getReceiveBufferSize();
 212                 }
 213             } catch (SocketException se) {
 214 
 215                 // connection will be emulated by DatagramSocket
 216                 connectState = ST_CONNECTED_NO_IMPL;
 217             }
 218         }
 219 
 220         connectedAddress = address;
 221         connectedPort = port;
 222     }
 223 
 224 
 225     /**
 226      * Constructs a datagram socket and binds it to any available port
 227      * on the local host machine.  The socket will be bound to the
 228      * {@link InetAddress#isAnyLocalAddress wildcard} address,
 229      * an IP address chosen by the kernel.
 230      *
 231      * <p>If there is a security manager,
 232      * its {@code checkListen} method is first called
 233      * with 0 as its argument to ensure the operation is allowed.
 234      * This could result in a SecurityException.
 235      *
 236      * @throws     SocketException  if the socket could not be opened,
 237      *               or the socket could not bind to the specified local port.
 238      * @throws     SecurityException  if a security manager exists and its
 239      *             {@code checkListen} method doesn't allow the operation.
 240      *
 241      * @see SecurityManager#checkListen
 242      */
 243     public DatagramSocket() throws SocketException {
 244         this(new InetSocketAddress(0));
 245     }
 246 
 247     /**
 248      * Creates an unbound datagram socket with the specified
 249      * DatagramSocketImpl.
 250      *
 251      * @param impl an instance of a <B>DatagramSocketImpl</B>
 252      *        the subclass wishes to use on the DatagramSocket.
 253      * @since   1.4
 254      */
 255     protected DatagramSocket(DatagramSocketImpl impl) {
 256         if (impl == null)
 257             throw new NullPointerException();
 258         this.impl = impl;
 259         checkOldImpl();
 260     }
 261 
 262     /**
 263      * Creates a datagram socket, bound to the specified local
 264      * socket address.
 265      * <p>
 266      * If, if the address is {@code null}, creates an unbound socket.
 267      *
 268      * <p>If there is a security manager,
 269      * its {@code checkListen} method is first called
 270      * with the port from the socket address
 271      * as its argument to ensure the operation is allowed.
 272      * This could result in a SecurityException.
 273      *
 274      * @param bindaddr local socket address to bind, or {@code null}
 275      *                 for an unbound socket.
 276      *
 277      * @throws     SocketException  if the socket could not be opened,
 278      *               or the socket could not bind to the specified local port.
 279      * @throws     SecurityException  if a security manager exists and its
 280      *             {@code checkListen} method doesn't allow the operation.
 281      *
 282      * @see SecurityManager#checkListen
 283      * @since   1.4
 284      */
 285     public DatagramSocket(SocketAddress bindaddr) throws SocketException {
 286         // create a datagram socket.
 287         createImpl();
 288         if (bindaddr != null) {
 289             try {
 290                 bind(bindaddr);
 291             } finally {
 292                 if (!isBound())
 293                     close();
 294             }
 295         }
 296     }
 297 
 298     /**
 299      * Constructs a datagram socket and binds it to the specified port
 300      * on the local host machine.  The socket will be bound to the
 301      * {@link InetAddress#isAnyLocalAddress wildcard} address,
 302      * an IP address chosen by the kernel.
 303      *
 304      * <p>If there is a security manager,
 305      * its {@code checkListen} method is first called
 306      * with the {@code port} argument
 307      * as its argument to ensure the operation is allowed.
 308      * This could result in a SecurityException.
 309      *
 310      * @param      port port to use.
 311      * @throws     SocketException  if the socket could not be opened,
 312      *               or the socket could not bind to the specified local port.
 313      * @throws     SecurityException  if a security manager exists and its
 314      *             {@code checkListen} method doesn't allow the operation.
 315      *
 316      * @see SecurityManager#checkListen
 317      */
 318     public DatagramSocket(int port) throws SocketException {
 319         this(port, null);
 320     }
 321 
 322     /**
 323      * Creates a datagram socket, bound to the specified local
 324      * address.  The local port must be between 0 and 65535 inclusive.
 325      * If the IP address is 0.0.0.0, the socket will be bound to the
 326      * {@link InetAddress#isAnyLocalAddress wildcard} address,
 327      * an IP address chosen by the kernel.
 328      *
 329      * <p>If there is a security manager,
 330      * its {@code checkListen} method is first called
 331      * with the {@code port} argument
 332      * as its argument to ensure the operation is allowed.
 333      * This could result in a SecurityException.
 334      *
 335      * @param port local port to use
 336      * @param laddr local address to bind
 337      *
 338      * @throws     SocketException  if the socket could not be opened,
 339      *               or the socket could not bind to the specified local port.
 340      * @throws     SecurityException  if a security manager exists and its
 341      *             {@code checkListen} method doesn't allow the operation.
 342      *
 343      * @see SecurityManager#checkListen
 344      * @since   1.1
 345      */
 346     public DatagramSocket(int port, InetAddress laddr) throws SocketException {
 347         this(new InetSocketAddress(laddr, port));
 348     }
 349 
 350     private void checkOldImpl() {
 351         if (impl == null)
 352             return;
 353         // DatagramSocketImpl.peekData() is a protected method, therefore we need to use
 354         // getDeclaredMethod, therefore we need permission to access the member
 355         try {
 356             AccessController.doPrivileged(
 357                 new PrivilegedExceptionAction<>() {
 358                     public Void run() throws NoSuchMethodException {
 359                         Class<?>[] cl = new Class<?>[1];
 360                         cl[0] = DatagramPacket.class;
 361                         impl.getClass().getDeclaredMethod("peekData", cl);
 362                         return null;
 363                     }
 364                 });
 365         } catch (java.security.PrivilegedActionException e) {
 366             oldImpl = true;
 367         }
 368     }
 369 
 370     static Class<?> implClass = null;
 371 
 372     void createImpl() throws SocketException {
 373         if (impl == null) {
 374             if (factory != null) {
 375                 impl = factory.createDatagramSocketImpl();
 376                 checkOldImpl();
 377             } else {
 378                 boolean isMulticast = (this instanceof MulticastSocket) ? true : false;
 379                 impl = DefaultDatagramSocketImplFactory.createDatagramSocketImpl(isMulticast);
 380 
 381                 checkOldImpl();
 382             }
 383         }
 384         // creates a udp socket
 385         impl.create();
 386         created = true;
 387     }
 388 
 389     /**
 390      * Get the {@code DatagramSocketImpl} attached to this socket,
 391      * creating it if necessary.
 392      *
 393      * @return  the {@code DatagramSocketImpl} attached to that
 394      *          DatagramSocket
 395      * @throws SocketException if creation fails.
 396      * @since 1.4
 397      */
 398     DatagramSocketImpl getImpl() throws SocketException {
 399         if (!created)
 400             createImpl();
 401         return impl;
 402     }
 403 
 404     /**
 405      * Binds this DatagramSocket to a specific address and port.
 406      * <p>
 407      * If the address is {@code null}, then the system will pick up
 408      * an ephemeral port and a valid local address to bind the socket.
 409      *
 410      * @param   addr The address and port to bind to.
 411      * @throws  SocketException if any error happens during the bind, or if the
 412      *          socket is already bound.
 413      * @throws  SecurityException  if a security manager exists and its
 414      *             {@code checkListen} method doesn't allow the operation.
 415      * @throws IllegalArgumentException if addr is a SocketAddress subclass
 416      *         not supported by this socket.
 417      * @since 1.4
 418      */
 419     public synchronized void bind(SocketAddress addr) throws SocketException {
 420         if (isClosed())
 421             throw new SocketException("Socket is closed");
 422         if (isBound())
 423             throw new SocketException("already bound");
 424         if (addr == null)
 425             addr = new InetSocketAddress(0);
 426         if (!(addr instanceof InetSocketAddress))
 427             throw new IllegalArgumentException("Unsupported address type!");
 428         InetSocketAddress epoint = (InetSocketAddress) addr;
 429         if (epoint.isUnresolved())
 430             throw new SocketException("Unresolved address");
 431         InetAddress iaddr = epoint.getAddress();
 432         int port = epoint.getPort();
 433         checkAddress(iaddr, "bind");
 434         SecurityManager sec = System.getSecurityManager();
 435         if (sec != null) {
 436             sec.checkListen(port);
 437         }
 438         try {
 439             getImpl().bind(port, iaddr);
 440         } catch (SocketException e) {
 441             getImpl().close();
 442             throw e;
 443         }
 444         bound = true;
 445     }
 446 
 447     void checkAddress (InetAddress addr, String op) {
 448         if (addr == null) {
 449             return;
 450         }
 451         if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
 452             throw new IllegalArgumentException(op + ": invalid address type");
 453         }
 454     }
 455 
 456     /**
 457      * Connects the socket to a remote address for this socket. When a
 458      * socket is connected to a remote address, packets may only be
 459      * sent to or received from that address. By default a datagram
 460      * socket is not connected.
 461      *
 462      * <p>If the remote destination to which the socket is connected does not
 463      * exist, or is otherwise unreachable, and if an ICMP destination unreachable
 464      * packet has been received for that address, then a subsequent call to
 465      * send or receive may throw a PortUnreachableException. Note, there is no
 466      * guarantee that the exception will be thrown.
 467      *
 468      * <p> If a security manager has been installed then it is invoked to check
 469      * access to the remote address. Specifically, if the given {@code address}
 470      * is a {@link InetAddress#isMulticastAddress multicast address},
 471      * the security manager's {@link
 472      * java.lang.SecurityManager#checkMulticast(InetAddress)
 473      * checkMulticast} method is invoked with the given {@code address}.
 474      * Otherwise, the security manager's {@link
 475      * java.lang.SecurityManager#checkConnect(String,int) checkConnect}
 476      * and {@link java.lang.SecurityManager#checkAccept checkAccept} methods
 477      * are invoked, with the given {@code address} and {@code port}, to
 478      * verify that datagrams are permitted to be sent and received
 479      * respectively.
 480      *
 481      * <p> Care should be taken to ensure that a connected datagram socket
 482      * is not shared with untrusted code. When a socket is connected,
 483      * {@link #receive receive} and {@link #send send} <b>will not perform
 484      * any security checks</b> on incoming and outgoing packets, other than
 485      * matching the packet's and the socket's address and port. On a send
 486      * operation, if the packet's address is set and the packet's address
 487      * and the socket's address do not match, an {@code IllegalArgumentException}
 488      * will be thrown. A socket connected to a multicast address may only
 489      * be used to send packets.
 490      *
 491      * @param address the remote address for the socket
 492      *
 493      * @param port the remote port for the socket.
 494      *
 495      * @throws IllegalArgumentException
 496      *         if the address is null, or the port is out of range.
 497      *
 498      * @throws SecurityException
 499      *         if a security manager has been installed and it does
 500      *         not permit access to the given remote address
 501      *
 502      * @throws UncheckedIOException
 503      *         May be thrown by an implementation if connect fails,
 504      *         for example, if the destination address is non-routable
 505      *
 506      * @see #disconnect
 507      */
 508     public void connect(InetAddress address, int port) {
 509         try {
 510             connectInternal(address, port);
 511         } catch (SocketException se) {
 512             throw new UncheckedIOException("connect failed", se);
 513         }
 514     }
 515 
 516     /**
 517      * Connects this socket to a remote socket address (IP address + port number).
 518      *
 519      * <p> If given an {@link InetSocketAddress InetSocketAddress}, this method
 520      * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)}
 521      * with the given socket addresses IP address and port number.
 522      *
 523      * @param   addr    The remote address.
 524      *
 525      * @throws  SocketException
 526      *          if the connect fails
 527      *
 528      * @throws IllegalArgumentException
 529      *         if {@code addr} is {@code null}, or {@code addr} is a SocketAddress
 530      *         subclass not supported by this socket
 531      *
 532      * @throws SecurityException
 533      *         if a security manager has been installed and it does
 534      *         not permit access to the given remote address
 535      *
 536      * @since 1.4
 537      */
 538     public void connect(SocketAddress addr) throws SocketException {
 539         if (addr == null)
 540             throw new IllegalArgumentException("Address can't be null");
 541         if (!(addr instanceof InetSocketAddress))
 542             throw new IllegalArgumentException("Unsupported address type");
 543         InetSocketAddress epoint = (InetSocketAddress) addr;
 544         if (epoint.isUnresolved())
 545             throw new SocketException("Unresolved address");
 546         connectInternal(epoint.getAddress(), epoint.getPort());
 547     }
 548 
 549     /**
 550      * Disconnects the socket. If the socket is closed or not connected,
 551      * then this method has no effect.
 552      *
 553      * @apiNote If this method throws an UncheckedIOException, the socket
 554      * may be left in an unspecified state. It is strongly recommended that
 555      * the socket be closed when disconnect fails.
 556      *
 557      * @throws  UncheckedIOException
 558      *          May be thrown by an implementation if it fails to dissolve the
 559      *          association and restore the socket to a consistent state.
 560      *
 561      * @see #connect
 562      */
 563     public void disconnect() {
 564         synchronized (this) {
 565             if (isClosed())
 566                 return;
 567             if (connectState == ST_CONNECTED) {
 568                 impl.disconnect ();
 569             }
 570             connectedAddress = null;
 571             connectedPort = -1;
 572             connectState = ST_NOT_CONNECTED;
 573             explicitFilter = false;
 574         }
 575     }
 576 
 577     /**
 578      * Returns the binding state of the socket.
 579      * <p>
 580      * If the socket was bound prior to being {@link #close closed},
 581      * then this method will continue to return {@code true}
 582      * after the socket is closed.
 583      *
 584      * @return true if the socket successfully bound to an address
 585      * @since 1.4
 586      */
 587     public boolean isBound() {
 588         return bound;
 589     }
 590 
 591     /**
 592      * Returns the connection state of the socket.
 593      * <p>
 594      * If the socket was connected prior to being {@link #close closed},
 595      * then this method will continue to return {@code true}
 596      * after the socket is closed.
 597      *
 598      * @return true if the socket successfully connected to a server
 599      * @since 1.4
 600      */
 601     public boolean isConnected() {
 602         return connectState != ST_NOT_CONNECTED;
 603     }
 604 
 605     /**
 606      * Returns the address to which this socket is connected. Returns
 607      * {@code null} if the socket is not connected.
 608      * <p>
 609      * If the socket was connected prior to being {@link #close closed},
 610      * then this method will continue to return the connected address
 611      * after the socket is closed.
 612      *
 613      * @return the address to which this socket is connected.
 614      */
 615     public InetAddress getInetAddress() {
 616         return connectedAddress;
 617     }
 618 
 619     /**
 620      * Returns the port number to which this socket is connected.
 621      * Returns {@code -1} if the socket is not connected.
 622      * <p>
 623      * If the socket was connected prior to being {@link #close closed},
 624      * then this method will continue to return the connected port number
 625      * after the socket is closed.
 626      *
 627      * @return the port number to which this socket is connected.
 628      */
 629     public int getPort() {
 630         return connectedPort;
 631     }
 632 
 633     /**
 634      * Returns the address of the endpoint this socket is connected to, or
 635      * {@code null} if it is unconnected.
 636      * <p>
 637      * If the socket was connected prior to being {@link #close closed},
 638      * then this method will continue to return the connected address
 639      * after the socket is closed.
 640      *
 641      * @return a {@code SocketAddress} representing the remote
 642      *         endpoint of this socket, or {@code null} if it is
 643      *         not connected yet.
 644      * @see #getInetAddress()
 645      * @see #getPort()
 646      * @see #connect(SocketAddress)
 647      * @since 1.4
 648      */
 649     public SocketAddress getRemoteSocketAddress() {
 650         if (!isConnected())
 651             return null;
 652         return new InetSocketAddress(getInetAddress(), getPort());
 653     }
 654 
 655     /**
 656      * Returns the address of the endpoint this socket is bound to.
 657      *
 658      * @return a {@code SocketAddress} representing the local endpoint of this
 659      *         socket, or {@code null} if it is closed or not bound yet.
 660      * @see #getLocalAddress()
 661      * @see #getLocalPort()
 662      * @see #bind(SocketAddress)
 663      * @since 1.4
 664      */
 665     public SocketAddress getLocalSocketAddress() {
 666         if (isClosed())
 667             return null;
 668         if (!isBound())
 669             return null;
 670         return new InetSocketAddress(getLocalAddress(), getLocalPort());
 671     }
 672 
 673     /**
 674      * Sends a datagram packet from this socket. The
 675      * {@code DatagramPacket} includes information indicating the
 676      * data to be sent, its length, the IP address of the remote host,
 677      * and the port number on the remote host.
 678      *
 679      * <p>If there is a security manager, and the socket is not currently
 680      * connected to a remote address, this method first performs some
 681      * security checks. First, if {@code p.getAddress().isMulticastAddress()}
 682      * is true, this method calls the
 683      * security manager's {@code checkMulticast} method
 684      * with {@code p.getAddress()} as its argument.
 685      * If the evaluation of that expression is false,
 686      * this method instead calls the security manager's
 687      * {@code checkConnect} method with arguments
 688      * {@code p.getAddress().getHostAddress()} and
 689      * {@code p.getPort()}. Each call to a security manager method
 690      * could result in a SecurityException if the operation is not allowed.
 691      *
 692      * @param      p   the {@code DatagramPacket} to be sent.
 693      *
 694      * @throws     IOException  if an I/O error occurs.
 695      * @throws     SecurityException  if a security manager exists and its
 696      *             {@code checkMulticast} or {@code checkConnect}
 697      *             method doesn't allow the send.
 698      * @throws     PortUnreachableException may be thrown if the socket is connected
 699      *             to a currently unreachable destination. Note, there is no
 700      *             guarantee that the exception will be thrown.
 701      * @throws     java.nio.channels.IllegalBlockingModeException
 702      *             if this socket has an associated channel,
 703      *             and the channel is in non-blocking mode.
 704      * @throws     IllegalArgumentException if the socket is connected,
 705      *             and connected address and packet address differ, or
 706      *             if the socket is not connected and the packet address
 707      *             is not set.
 708      *
 709      * @see        java.net.DatagramPacket
 710      * @see        SecurityManager#checkMulticast(InetAddress)
 711      * @see        SecurityManager#checkConnect
 712      * @revised 1.4
 713      * @spec JSR-51
 714      */
 715     public void send(DatagramPacket p) throws IOException  {
 716         synchronized (p) {
 717             if (isClosed())
 718                 throw new SocketException("Socket is closed");
 719             InetAddress packetAddress = p.getAddress();
 720             checkAddress (packetAddress, "send");
 721             if (connectState == ST_NOT_CONNECTED) {
 722                 if (packetAddress == null) {
 723                     throw new IllegalArgumentException("Address not set");
 724                 }
 725                 // check the address is ok with the security manager on every send.
 726                 SecurityManager security = System.getSecurityManager();
 727 
 728                 // The reason you want to synchronize on datagram packet
 729                 // is because you don't want an applet to change the address
 730                 // while you are trying to send the packet for example
 731                 // after the security check but before the send.
 732                 if (security != null) {
 733                     if (packetAddress.isMulticastAddress()) {
 734                         security.checkMulticast(packetAddress);
 735                     } else {
 736                         security.checkConnect(packetAddress.getHostAddress(),
 737                                               p.getPort());
 738                     }
 739                 }
 740             } else {
 741                 // we're connected
 742                 if (packetAddress == null) {
 743                     p.setAddress(connectedAddress);
 744                     p.setPort(connectedPort);
 745                 } else if ((!packetAddress.equals(connectedAddress)) ||
 746                            p.getPort() != connectedPort) {
 747                     throw new IllegalArgumentException("connected address " +
 748                                                        "and packet address" +
 749                                                        " differ");
 750                 }
 751             }
 752             // Check whether the socket is bound
 753             if (!isBound())
 754                 bind(new InetSocketAddress(0));
 755             // call the  method to send
 756             getImpl().send(p);
 757         }
 758     }
 759 
 760     /**
 761      * Receives a datagram packet from this socket. When this method
 762      * returns, the {@code DatagramPacket}'s buffer is filled with
 763      * the data received. The datagram packet also contains the sender's
 764      * IP address, and the port number on the sender's machine.
 765      * <p>
 766      * This method blocks until a datagram is received. The
 767      * {@code length} field of the datagram packet object contains
 768      * the length of the received message. If the message is longer than
 769      * the packet's length, the message is truncated.
 770      * <p>
 771      * If there is a security manager, and the socket is not currently
 772      * connected to a remote address, a packet cannot be received if the
 773      * security manager's {@code checkAccept} method does not allow it.
 774      * Datagrams that are not permitted by the security manager are silently
 775      * discarded.
 776      *
 777      * @param      p   the {@code DatagramPacket} into which to place
 778      *                 the incoming data.
 779      * @throws     IOException  if an I/O error occurs.
 780      * @throws     SocketTimeoutException  if setSoTimeout was previously called
 781      *                 and the timeout has expired.
 782      * @throws     PortUnreachableException may be thrown if the socket is connected
 783      *             to a currently unreachable destination. Note, there is no guarantee that the
 784      *             exception will be thrown.
 785      * @throws     java.nio.channels.IllegalBlockingModeException
 786      *             if this socket has an associated channel,
 787      *             and the channel is in non-blocking mode.
 788      * @see        java.net.DatagramPacket
 789      * @see        java.net.DatagramSocket
 790      * @revised 1.4
 791      * @spec JSR-51
 792      */
 793     public synchronized void receive(DatagramPacket p) throws IOException {
 794         synchronized (p) {
 795             if (!isBound())
 796                 bind(new InetSocketAddress(0));
 797             if (connectState == ST_NOT_CONNECTED) {
 798                 // check the address is ok with the security manager before every recv.
 799                 SecurityManager security = System.getSecurityManager();
 800                 if (security != null) {
 801                     while(true) {
 802                         String peekAd = null;
 803                         int peekPort = 0;
 804                         // peek at the packet to see who it is from.
 805                         if (!oldImpl) {
 806                             // We can use the new peekData() API
 807                             DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
 808                             peekPort = getImpl().peekData(peekPacket);
 809                             peekAd = peekPacket.getAddress().getHostAddress();
 810                         } else {
 811                             InetAddress adr = new InetAddress();
 812                             peekPort = getImpl().peek(adr);
 813                             peekAd = adr.getHostAddress();
 814                         }
 815                         try {
 816                             security.checkAccept(peekAd, peekPort);
 817                             // security check succeeded - so now break
 818                             // and recv the packet.
 819                             break;
 820                         } catch (SecurityException se) {
 821                             // Throw away the offending packet by consuming
 822                             // it in a tmp buffer.
 823                             DatagramPacket tmp = new DatagramPacket(new byte[1], 1);
 824                             getImpl().receive(tmp);
 825 
 826                             // silently discard the offending packet
 827                             // and continue: unknown/malicious
 828                             // entities on nets should not make
 829                             // runtime throw security exception and
 830                             // disrupt the applet by sending random
 831                             // datagram packets.
 832                             continue;
 833                         }
 834                     } // end of while
 835                 }
 836             }
 837             DatagramPacket tmp = null;
 838             if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) {
 839                 // We have to do the filtering the old fashioned way since
 840                 // the native impl doesn't support connect or the connect
 841                 // via the impl failed, or .. "explicitFilter" may be set when
 842                 // a socket is connected via the impl, for a period of time
 843                 // when packets from other sources might be queued on socket.
 844                 boolean stop = false;
 845                 while (!stop) {
 846                     InetAddress peekAddress = null;
 847                     int peekPort = -1;
 848                     // peek at the packet to see who it is from.
 849                     if (!oldImpl) {
 850                         // We can use the new peekData() API
 851                         DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
 852                         peekPort = getImpl().peekData(peekPacket);
 853                         peekAddress = peekPacket.getAddress();
 854                     } else {
 855                         // this api only works for IPv4
 856                         peekAddress = new InetAddress();
 857                         peekPort = getImpl().peek(peekAddress);
 858                     }
 859                     if ((!connectedAddress.equals(peekAddress)) ||
 860                         (connectedPort != peekPort)) {
 861                         // throw the packet away and silently continue
 862                         tmp = new DatagramPacket(
 863                                                 new byte[1024], 1024);
 864                         getImpl().receive(tmp);
 865                         if (explicitFilter) {
 866                             if (checkFiltering(tmp)) {
 867                                 stop = true;
 868                             }
 869                         }
 870                     } else {
 871                         stop = true;
 872                     }
 873                 }
 874             }
 875             // If the security check succeeds, or the datagram is
 876             // connected then receive the packet
 877             getImpl().receive(p);
 878             if (explicitFilter && tmp == null) {
 879                 // packet was not filtered, account for it here
 880                 checkFiltering(p);
 881             }
 882         }
 883     }
 884 
 885     private boolean checkFiltering(DatagramPacket p) throws SocketException {
 886         bytesLeftToFilter -= p.getLength();
 887         if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) {
 888             explicitFilter = false;
 889             return true;
 890         }
 891         return false;
 892     }
 893 
 894     /**
 895      * Gets the local address to which the socket is bound.
 896      *
 897      * <p>If there is a security manager, its
 898      * {@code checkConnect} method is first called
 899      * with the host address and {@code -1}
 900      * as its arguments to see if the operation is allowed.
 901      *
 902      * @see SecurityManager#checkConnect
 903      * @return  the local address to which the socket is bound,
 904      *          {@code null} if the socket is closed, or
 905      *          an {@code InetAddress} representing
 906      *          {@link InetAddress#isAnyLocalAddress wildcard}
 907      *          address if either the socket is not bound, or
 908      *          the security manager {@code checkConnect}
 909      *          method does not allow the operation
 910      * @since   1.1
 911      */
 912     public InetAddress getLocalAddress() {
 913         if (isClosed())
 914             return null;
 915         InetAddress in;
 916         try {
 917             in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
 918             if (in.isAnyLocalAddress()) {
 919                 in = InetAddress.anyLocalAddress();
 920             }
 921             SecurityManager s = System.getSecurityManager();
 922             if (s != null) {
 923                 s.checkConnect(in.getHostAddress(), -1);
 924             }
 925         } catch (Exception e) {
 926             in = InetAddress.anyLocalAddress(); // "0.0.0.0"
 927         }
 928         return in;
 929     }
 930 
 931     /**
 932      * Returns the port number on the local host to which this socket
 933      * is bound.
 934      *
 935      * @return  the port number on the local host to which this socket is bound,
 936      *          {@code -1} if the socket is closed, or
 937      *          {@code 0} if it is not bound yet.
 938      */
 939     public int getLocalPort() {
 940         if (isClosed())
 941             return -1;
 942         try {
 943             return getImpl().getLocalPort();
 944         } catch (Exception e) {
 945             return 0;
 946         }
 947     }
 948 
 949     /**
 950      * Enable/disable SO_TIMEOUT with the specified timeout, in
 951      * milliseconds. With this option set to a positive timeout value,
 952      * a call to receive() for this DatagramSocket
 953      * will block for only this amount of time.  If the timeout expires,
 954      * a <B>java.net.SocketTimeoutException</B> is raised, though the
 955      * DatagramSocket is still valid. A timeout of zero is interpreted
 956      * as an infinite timeout.
 957      * The option <B>must</B> be enabled prior to entering the blocking
 958      * operation to have effect.
 959      *
 960      * @param timeout the specified timeout in milliseconds.
 961      * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
 962      * @throws IllegalArgumentException if {@code timeout} is negative
 963      * @since   1.1
 964      * @see #getSoTimeout()
 965      */
 966     public synchronized void setSoTimeout(int timeout) throws SocketException {
 967         if (isClosed())
 968             throw new SocketException("Socket is closed");
 969         if (timeout < 0)
 970             throw new IllegalArgumentException("timeout < 0");
 971         getImpl().setOption(SocketOptions.SO_TIMEOUT, timeout);
 972     }
 973 
 974     /**
 975      * Retrieve setting for SO_TIMEOUT.  0 returns implies that the
 976      * option is disabled (i.e., timeout of infinity).
 977      *
 978      * @return the setting for SO_TIMEOUT
 979      * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
 980      * @since   1.1
 981      * @see #setSoTimeout(int)
 982      */
 983     public synchronized int getSoTimeout() throws SocketException {
 984         if (isClosed())
 985             throw new SocketException("Socket is closed");
 986         if (getImpl() == null)
 987             return 0;
 988         Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
 989         /* extra type safety */
 990         if (o instanceof Integer) {
 991             return ((Integer) o).intValue();
 992         } else {
 993             return 0;
 994         }
 995     }
 996 
 997     /**
 998      * Sets the SO_SNDBUF option to the specified value for this
 999      * {@code DatagramSocket}. The SO_SNDBUF option is used by the
1000      * network implementation as a hint to size the underlying
1001      * network I/O buffers. The SO_SNDBUF setting may also be used
1002      * by the network implementation to determine the maximum size
1003      * of the packet that can be sent on this socket.
1004      * <p>
1005      * As SO_SNDBUF is a hint, applications that want to verify
1006      * what size the buffer is should call {@link #getSendBufferSize()}.
1007      * <p>
1008      * Increasing the buffer size may allow multiple outgoing packets
1009      * to be queued by the network implementation when the send rate
1010      * is high.
1011      * <p>
1012      * Note: If {@link #send(DatagramPacket)} is used to send a
1013      * {@code DatagramPacket} that is larger than the setting
1014      * of SO_SNDBUF then it is implementation specific if the
1015      * packet is sent or discarded.
1016      *
1017      * @param size the size to which to set the send buffer
1018      * size. This value must be greater than 0.
1019      *
1020      * @throws    SocketException if there is an error
1021      * in the underlying protocol, such as an UDP error.
1022      * @throws    IllegalArgumentException if the value is 0 or is
1023      * negative.
1024      * @see #getSendBufferSize()
1025      */
1026     public synchronized void setSendBufferSize(int size) throws SocketException {
1027         if (!(size > 0)) {
1028             throw new IllegalArgumentException("negative send size");
1029         }
1030         if (isClosed())
1031             throw new SocketException("Socket is closed");
1032         getImpl().setOption(SocketOptions.SO_SNDBUF, size);
1033     }
1034 
1035     /**
1036      * Get value of the SO_SNDBUF option for this {@code DatagramSocket}, that is the
1037      * buffer size used by the platform for output on this {@code DatagramSocket}.
1038      *
1039      * @return the value of the SO_SNDBUF option for this {@code DatagramSocket}
1040      * @throws    SocketException if there is an error in
1041      * the underlying protocol, such as an UDP error.
1042      * @see #setSendBufferSize
1043      */
1044     public synchronized int getSendBufferSize() throws SocketException {
1045         if (isClosed())
1046             throw new SocketException("Socket is closed");
1047         int result = 0;
1048         Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
1049         if (o instanceof Integer) {
1050             result = ((Integer)o).intValue();
1051         }
1052         return result;
1053     }
1054 
1055     /**
1056      * Sets the SO_RCVBUF option to the specified value for this
1057      * {@code DatagramSocket}. The SO_RCVBUF option is used by
1058      * the network implementation as a hint to size the underlying
1059      * network I/O buffers. The SO_RCVBUF setting may also be used
1060      * by the network implementation to determine the maximum size
1061      * of the packet that can be received on this socket.
1062      * <p>
1063      * Because SO_RCVBUF is a hint, applications that want to
1064      * verify what size the buffers were set to should call
1065      * {@link #getReceiveBufferSize()}.
1066      * <p>
1067      * Increasing SO_RCVBUF may allow the network implementation
1068      * to buffer multiple packets when packets arrive faster than
1069      * are being received using {@link #receive(DatagramPacket)}.
1070      * <p>
1071      * Note: It is implementation specific if a packet larger
1072      * than SO_RCVBUF can be received.
1073      *
1074      * @param size the size to which to set the receive buffer
1075      * size. This value must be greater than 0.
1076      *
1077      * @throws    SocketException if there is an error in
1078      * the underlying protocol, such as an UDP error.
1079      * @throws    IllegalArgumentException if the value is 0 or is
1080      * negative.
1081      * @see #getReceiveBufferSize()
1082      */
1083     public synchronized void setReceiveBufferSize(int size) throws SocketException {
1084         if (size <= 0) {
1085             throw new IllegalArgumentException("invalid receive size");
1086         }
1087         if (isClosed())
1088             throw new SocketException("Socket is closed");
1089         getImpl().setOption(SocketOptions.SO_RCVBUF, size);
1090     }
1091 
1092     /**
1093      * Get value of the SO_RCVBUF option for this {@code DatagramSocket}, that is the
1094      * buffer size used by the platform for input on this {@code DatagramSocket}.
1095      *
1096      * @return the value of the SO_RCVBUF option for this {@code DatagramSocket}
1097      * @throws    SocketException if there is an error in the underlying protocol, such as an UDP error.
1098      * @see #setReceiveBufferSize(int)
1099      */
1100     public synchronized int getReceiveBufferSize() throws SocketException {
1101         if (isClosed())
1102             throw new SocketException("Socket is closed");
1103         int result = 0;
1104         Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
1105         if (o instanceof Integer) {
1106             result = ((Integer)o).intValue();
1107         }
1108         return result;
1109     }
1110 
1111     /**
1112      * Enable/disable the SO_REUSEADDR socket option.
1113      * <p>
1114      * For UDP sockets it may be necessary to bind more than one
1115      * socket to the same socket address. This is typically for the
1116      * purpose of receiving multicast packets
1117      * (See {@link java.net.MulticastSocket}). The
1118      * {@code SO_REUSEADDR} socket option allows multiple
1119      * sockets to be bound to the same socket address if the
1120      * {@code SO_REUSEADDR} socket option is enabled prior
1121      * to binding the socket using {@link #bind(SocketAddress)}.
1122      * <p>
1123      * Note: This functionality is not supported by all existing platforms,
1124      * so it is implementation specific whether this option will be ignored
1125      * or not. However, if it is not supported then
1126      * {@link #getReuseAddress()} will always return {@code false}.
1127      * <p>
1128      * When a {@code DatagramSocket} is created the initial setting
1129      * of {@code SO_REUSEADDR} is disabled.
1130      * <p>
1131      * The behaviour when {@code SO_REUSEADDR} is enabled or
1132      * disabled after a socket is bound (See {@link #isBound()})
1133      * is not defined.
1134      *
1135      * @param on  whether to enable or disable the
1136      * @throws    SocketException if an error occurs enabling or
1137      *            disabling the {@code SO_REUSEADDR} socket option,
1138      *            or the socket is closed.
1139      * @since 1.4
1140      * @see #getReuseAddress()
1141      * @see #bind(SocketAddress)
1142      * @see #isBound()
1143      * @see #isClosed()
1144      */
1145     public synchronized void setReuseAddress(boolean on) throws SocketException {
1146         if (isClosed())
1147             throw new SocketException("Socket is closed");
1148         // Integer instead of Boolean for compatibility with older DatagramSocketImpl
1149         if (oldImpl)
1150             getImpl().setOption(SocketOptions.SO_REUSEADDR, on?-1:0);
1151         else
1152             getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
1153     }
1154 
1155     /**
1156      * Tests if SO_REUSEADDR is enabled.
1157      *
1158      * @return a {@code boolean} indicating whether or not SO_REUSEADDR is enabled.
1159      * @throws    SocketException if there is an error
1160      * in the underlying protocol, such as an UDP error.
1161      * @since   1.4
1162      * @see #setReuseAddress(boolean)
1163      */
1164     public synchronized boolean getReuseAddress() throws SocketException {
1165         if (isClosed())
1166             throw new SocketException("Socket is closed");
1167         Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR);
1168         return ((Boolean)o).booleanValue();
1169     }
1170 
1171     /**
1172      * Enable/disable SO_BROADCAST.
1173      *
1174      * <p> Some operating systems may require that the Java virtual machine be
1175      * started with implementation specific privileges to enable this option or
1176      * send broadcast datagrams.
1177      *
1178      * @param  on
1179      *         whether or not to have broadcast turned on.
1180      *
1181      * @throws  SocketException
1182      *          if there is an error in the underlying protocol, such as an UDP
1183      *          error.
1184      *
1185      * @since 1.4
1186      * @see #getBroadcast()
1187      */
1188     public synchronized void setBroadcast(boolean on) throws SocketException {
1189         if (isClosed())
1190             throw new SocketException("Socket is closed");
1191         getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(on));
1192     }
1193 
1194     /**
1195      * Tests if SO_BROADCAST is enabled.
1196      * @return a {@code boolean} indicating whether or not SO_BROADCAST is enabled.
1197      * @throws    SocketException if there is an error
1198      * in the underlying protocol, such as an UDP error.
1199      * @since 1.4
1200      * @see #setBroadcast(boolean)
1201      */
1202     public synchronized boolean getBroadcast() throws SocketException {
1203         if (isClosed())
1204             throw new SocketException("Socket is closed");
1205         return ((Boolean)(getImpl().getOption(SocketOptions.SO_BROADCAST))).booleanValue();
1206     }
1207 
1208     /**
1209      * Sets traffic class or type-of-service octet in the IP
1210      * datagram header for datagrams sent from this DatagramSocket.
1211      * As the underlying network implementation may ignore this
1212      * value applications should consider it a hint.
1213      *
1214      * <P> The tc <B>must</B> be in the range {@code 0 <= tc <=
1215      * 255} or an IllegalArgumentException will be thrown.
1216      * <p>Notes:
1217      * <p>For Internet Protocol v4 the value consists of an
1218      * {@code integer}, the least significant 8 bits of which
1219      * represent the value of the TOS octet in IP packets sent by
1220      * the socket.
1221      * RFC 1349 defines the TOS values as follows:
1222      *
1223      * <UL>
1224      * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
1225      * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
1226      * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
1227      * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
1228      * </UL>
1229      * The last low order bit is always ignored as this
1230      * corresponds to the MBZ (must be zero) bit.
1231      * <p>
1232      * Setting bits in the precedence field may result in a
1233      * SocketException indicating that the operation is not
1234      * permitted.
1235      * <p>
1236      * for Internet Protocol v6 {@code tc} is the value that
1237      * would be placed into the sin6_flowinfo field of the IP header.
1238      *
1239      * @param tc        an {@code int} value for the bitset.
1240      * @throws SocketException if there is an error setting the
1241      * traffic class or type-of-service
1242      * @since 1.4
1243      * @see #getTrafficClass
1244      */
1245     public synchronized void setTrafficClass(int tc) throws SocketException {
1246         if (tc < 0 || tc > 255)
1247             throw new IllegalArgumentException("tc is not in range 0 -- 255");
1248 
1249         if (isClosed())
1250             throw new SocketException("Socket is closed");
1251         try {
1252             getImpl().setOption(SocketOptions.IP_TOS, tc);
1253         } catch (SocketException se) {
1254             // not supported if socket already connected
1255             // Solaris returns error in such cases
1256             if(!isConnected())
1257                 throw se;
1258         }
1259     }
1260 
1261     /**
1262      * Gets traffic class or type-of-service in the IP datagram
1263      * header for packets sent from this DatagramSocket.
1264      * <p>
1265      * As the underlying network implementation may ignore the
1266      * traffic class or type-of-service set using {@link #setTrafficClass(int)}
1267      * this method may return a different value than was previously
1268      * set using the {@link #setTrafficClass(int)} method on this
1269      * DatagramSocket.
1270      *
1271      * @return the traffic class or type-of-service already set
1272      * @throws SocketException if there is an error obtaining the
1273      * traffic class or type-of-service value.
1274      * @since 1.4
1275      * @see #setTrafficClass(int)
1276      */
1277     public synchronized int getTrafficClass() throws SocketException {
1278         if (isClosed())
1279             throw new SocketException("Socket is closed");
1280         return ((Integer)(getImpl().getOption(SocketOptions.IP_TOS))).intValue();
1281     }
1282 
1283     /**
1284      * Closes this datagram socket.
1285      * <p>
1286      * Any thread currently blocked in {@link #receive} upon this socket
1287      * will throw a {@link SocketException}.
1288      *
1289      * <p> If this socket has an associated channel then the channel is closed
1290      * as well.
1291      *
1292      * @revised 1.4
1293      * @spec JSR-51
1294      */
1295     public void close() {
1296         synchronized(closeLock) {
1297             if (isClosed())
1298                 return;
1299             impl.close();
1300             closed = true;
1301         }
1302     }
1303 
1304     /**
1305      * Returns whether the socket is closed or not.
1306      *
1307      * @return true if the socket has been closed
1308      * @since 1.4
1309      */
1310     public boolean isClosed() {
1311         synchronized(closeLock) {
1312             return closed;
1313         }
1314     }
1315 
1316     /**
1317      * Returns the unique {@link java.nio.channels.DatagramChannel} object
1318      * associated with this datagram socket, if any.
1319      *
1320      * <p> A datagram socket will have a channel if, and only if, the channel
1321      * itself was created via the {@link java.nio.channels.DatagramChannel#open
1322      * DatagramChannel.open} method.
1323      *
1324      * @return  the datagram channel associated with this datagram socket,
1325      *          or {@code null} if this socket was not created for a channel
1326      *
1327      * @since 1.4
1328      * @spec JSR-51
1329      */
1330     public DatagramChannel getChannel() {
1331         return null;
1332     }
1333 
1334     /**
1335      * User defined factory for all datagram sockets.
1336      */
1337     static DatagramSocketImplFactory factory;
1338 
1339     /**
1340      * Sets the datagram socket implementation factory for the
1341      * application. The factory can be specified only once.
1342      * <p>
1343      * When an application creates a new datagram socket, the socket
1344      * implementation factory's {@code createDatagramSocketImpl} method is
1345      * called to create the actual datagram socket implementation.
1346      * <p>
1347      * Passing {@code null} to the method is a no-op unless the factory
1348      * was already set.
1349      *
1350      * <p>If there is a security manager, this method first calls
1351      * the security manager's {@code checkSetFactory} method
1352      * to ensure the operation is allowed.
1353      * This could result in a SecurityException.
1354      *
1355      * @param      fac   the desired factory.
1356      * @throws     IOException  if an I/O error occurs when setting the
1357      *              datagram socket factory.
1358      * @throws     SocketException  if the factory is already defined.
1359      * @throws     SecurityException  if a security manager exists and its
1360      *             {@code checkSetFactory} method doesn't allow the operation.
1361      * @see       java.net.DatagramSocketImplFactory#createDatagramSocketImpl()
1362      * @see       SecurityManager#checkSetFactory
1363      * @since 1.3
1364      */
1365     public static synchronized void
1366     setDatagramSocketImplFactory(DatagramSocketImplFactory fac)
1367        throws IOException
1368     {
1369         if (factory != null) {
1370             throw new SocketException("factory already defined");
1371         }
1372         SecurityManager security = System.getSecurityManager();
1373         if (security != null) {
1374             security.checkSetFactory();
1375         }
1376         factory = fac;
1377     }
1378 
1379     /**
1380      * Sets the value of a socket option.
1381      *
1382      * @param <T> The type of the socket option value
1383      * @param name The socket option
1384      * @param value The value of the socket option. A value of {@code null}
1385      *              may be valid for some options.
1386      *
1387      * @return this DatagramSocket
1388      *
1389      * @throws UnsupportedOperationException if the datagram socket
1390      *         does not support the option.
1391      *
1392      * @throws IllegalArgumentException if the value is not valid for
1393      *         the option.
1394      *
1395      * @throws IOException if an I/O error occurs, or if the socket is closed.
1396      *
1397      * @throws SecurityException if a security manager is set and if the socket
1398      *         option requires a security permission and if the caller does
1399      *         not have the required permission.
1400      *         {@link java.net.StandardSocketOptions StandardSocketOptions}
1401      *         do not require any security permission.
1402      *
1403      * @throws NullPointerException if name is {@code null}
1404      *
1405      * @since 9
1406      */
1407     public <T> DatagramSocket setOption(SocketOption<T> name, T value)
1408         throws IOException
1409     {
1410         Objects.requireNonNull(name);
1411         if (isClosed())
1412             throw new SocketException("Socket is closed");
1413         getImpl().setOption(name, value);
1414         return this;
1415     }
1416 
1417     /**
1418      * Returns the value of a socket option.
1419      *
1420      * @param <T> The type of the socket option value
1421      * @param name The socket option
1422      *
1423      * @return The value of the socket option.
1424      *
1425      * @throws UnsupportedOperationException if the datagram socket
1426      *         does not support the option.
1427      *
1428      * @throws IOException if an I/O error occurs, or if the socket is closed.
1429      *
1430      * @throws NullPointerException if name is {@code null}
1431      *
1432      * @throws SecurityException if a security manager is set and if the socket
1433      *         option requires a security permission and if the caller does
1434      *         not have the required permission.
1435      *         {@link java.net.StandardSocketOptions StandardSocketOptions}
1436      *         do not require any security permission.
1437      *
1438      * @since 9
1439      */
1440     public <T> T getOption(SocketOption<T> name) throws IOException {
1441         Objects.requireNonNull(name);
1442         if (isClosed())
1443             throw new SocketException("Socket is closed");
1444         return getImpl().getOption(name);
1445     }
1446 
1447     private static Set<SocketOption<?>> options;
1448     private static boolean optionsSet = false;
1449 
1450     /**
1451      * Returns a set of the socket options supported by this socket.
1452      *
1453      * This method will continue to return the set of options even after
1454      * the socket has been closed.
1455      *
1456      * @return A set of the socket options supported by this socket. This set
1457      *        may be empty if the socket's DatagramSocketImpl cannot be created.
1458      *
1459      * @since 9
1460      */
1461     public Set<SocketOption<?>> supportedOptions() {
1462         synchronized(DatagramSocket.class) {
1463             if (optionsSet) {
1464                 return options;
1465             }
1466             try {
1467                 DatagramSocketImpl impl = getImpl();
1468                 options = Collections.unmodifiableSet(impl.supportedOptions());
1469             } catch (IOException e) {
1470                 options = Collections.emptySet();
1471             }
1472             optionsSet = true;
1473             return options;
1474         }
1475     }
1476 }
--- EOF ---