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.nio.channels.DatagramChannel;
  30 import java.security.AccessController;
  31 import java.security.PrivilegedExceptionAction;
  32 import java.util.Objects;
  33 import java.util.Set;
  34 import java.util.Collections;
  35 
  36 /**
  37  * This class represents a socket for sending and receiving datagram packets.
  38  *
  39  * <p>A datagram socket is the sending or receiving point for a packet
  40  * delivery service. Each packet sent or received on a datagram socket
  41  * is individually addressed and routed. Multiple packets sent from
  42  * one machine to another may be routed differently, and may arrive in
  43  * any order.
  44  *
  45  * <p> Where possible, a newly constructed {@code DatagramSocket} has the
  46  * {@link StandardSocketOptions#SO_BROADCAST SO_BROADCAST} socket option enabled so as
  47  * to allow the transmission of broadcast datagrams. In order to receive
  48  * broadcast packets a DatagramSocket should be bound to the wildcard address.
  49  * In some implementations, broadcast packets may also be received when
  50  * a DatagramSocket is bound to a more specific address.
  51  * <p>
  52  * Example:
  53  * <pre>{@code
  54  *              DatagramSocket s = new DatagramSocket(null);
  55  *              s.bind(new InetSocketAddress(8888));
  56  * }</pre>
  57  * Which is equivalent to:
  58  * <pre>{@code
  59  *              DatagramSocket s = new DatagramSocket(8888);
  60  * }</pre>
  61  * Both cases will create a DatagramSocket able to receive broadcasts on
  62  * UDP port 8888.
  63  *
  64  * <p> The {@code DatagramSocket} class defines convenience
  65  * methods to set and get several socket options. This class also
  66  * defines the {@link #setOption(SocketOption,Object) setOption}
  67  * and {@link #getOption(SocketOption) getOption} methods to set
  68  * and query socket options.
  69  * A {@code DatagramSocket} supports the following socket options:
  70  * <blockquote>
  71  * <a id="SocketOptions"></a>
  72  * <table class="striped">
  73  * <caption style="display:none">Socket options</caption>
  74  * <thead>
  75  *   <tr>
  76  *     <th scope="col">Option Name</th>
  77  *     <th scope="col">Description</th>
  78  *   </tr>
  79  * </thead>
  80  * <tbody>
  81  *   <tr>
  82  *     <th scope="row"> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </th>
  83  *     <td> The size of the socket send buffer </td>
  84  *   </tr>
  85  *   <tr>
  86  *     <th scope="row"> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </th>
  87  *     <td> The size of the socket receive buffer </td>
  88  *   </tr>
  89  *   <tr>
  90  *     <th scope="row"> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </th>
  91  *     <td> Re-use address </td>
  92  *   </tr>
  93  *   <tr>
  94  *     <th scope="row"> {@link java.net.StandardSocketOptions#SO_BROADCAST SO_BROADCAST} </th>
  95  *     <td> Allow transmission of broadcast datagrams </td>
  96  *   </tr>
  97  *   <tr>
  98  *     <th scope="row"> {@link java.net.StandardSocketOptions#IP_TOS IP_TOS} </th>
  99  *     <td> The Type of Service (ToS) octet in the Internet Protocol (IP) header </td>
 100  *   </tr>
 101  * </tbody>
 102  * </table>
 103  * </blockquote>
 104  * An implementation may also support additional options. In particular an implementation
 105  * may support <a href="MulticastSocket.html#MulticastOptions">multicast options</a> which
 106  * can be useful when using a plain {@code DatagramSocket} to send datagrams to a
 107  * multicast group.
 108  *
 109  * @author  Pavani Diwanji
 110  * @see     java.net.DatagramPacket
 111  * @see     java.nio.channels.DatagramChannel
 112  * @since 1.0
 113  */
 114 public class DatagramSocket implements java.io.Closeable {
 115     /**
 116      * Various states of this socket.
 117      */
 118     private boolean created = false;
 119     private boolean bound = false;
 120     private boolean closed = false;
 121     private Object closeLock = new Object();
 122 
 123     /*
 124      * The implementation of this DatagramSocket.
 125      */
 126     DatagramSocketImpl impl;
 127 
 128     /**
 129      * Are we using an older DatagramSocketImpl?
 130      */
 131     boolean oldImpl = false;
 132 
 133     /**
 134      * Set when a socket is ST_CONNECTED until we are certain
 135      * that any packets which might have been received prior
 136      * to calling connect() but not read by the application
 137      * have been read. During this time we check the source
 138      * address of all packets received to be sure they are from
 139      * the connected destination. Other packets are read but
 140      * silently dropped.
 141      */
 142     private boolean explicitFilter = false;
 143     private int bytesLeftToFilter;
 144     /*
 145      * Connection state:
 146      * ST_NOT_CONNECTED = socket not connected
 147      * ST_CONNECTED = socket connected
 148      * ST_CONNECTED_NO_IMPL = socket connected but not at impl level
 149      */
 150     static final int ST_NOT_CONNECTED = 0;
 151     static final int ST_CONNECTED = 1;
 152     static final int ST_CONNECTED_NO_IMPL = 2;
 153 
 154     int connectState = ST_NOT_CONNECTED;
 155 
 156     /*
 157      * Connected address & port
 158      */
 159     InetAddress connectedAddress = null;
 160     int connectedPort = -1;
 161 
 162     /**
 163      * Connects this socket to a remote socket address (IP address + port number).
 164      * Binds socket if not already bound.
 165      *
 166      * @param   address The remote address.
 167      * @param   port    The remote port
 168      * @throws  SocketException if binding the socket fails.
 169      */
 170     private synchronized void connectInternal(InetAddress address, int port) throws SocketException {
 171         if (port < 0 || port > 0xFFFF) {
 172             throw new IllegalArgumentException("connect: " + port);
 173         }
 174         if (address == null) {
 175             throw new IllegalArgumentException("connect: null address");
 176         }
 177         checkAddress (address, "connect");
 178         if (isClosed())
 179             return;
 180         SecurityManager security = System.getSecurityManager();
 181         if (security != null) {
 182             if (address.isMulticastAddress()) {
 183                 security.checkMulticast(address);
 184             } else {
 185                 security.checkConnect(address.getHostAddress(), port);
 186                 security.checkAccept(address.getHostAddress(), port);
 187             }
 188         }
 189 
 190         if (!isBound())
 191           bind(new InetSocketAddress(0));
 192 
 193         // old impls do not support connect/disconnect
 194         if (oldImpl || (impl instanceof AbstractPlainDatagramSocketImpl &&
 195              ((AbstractPlainDatagramSocketImpl)impl).nativeConnectDisabled())) {
 196             connectState = ST_CONNECTED_NO_IMPL;
 197         } else {
 198             try {
 199                 getImpl().connect(address, port);
 200 
 201                 // socket is now connected by the impl
 202                 connectState = ST_CONNECTED;
 203                 // Do we need to filter some packets?
 204                 int avail = getImpl().dataAvailable();
 205                 if (avail == -1) {
 206                     throw new SocketException();
 207                 }
 208                 explicitFilter = avail > 0;
 209                 if (explicitFilter) {
 210                     bytesLeftToFilter = getReceiveBufferSize();
 211                 }
 212             } catch (SocketException se) {
 213 
 214                 // connection will be emulated by DatagramSocket
 215                 connectState = ST_CONNECTED_NO_IMPL;
 216             }
 217         }
 218 
 219         connectedAddress = address;
 220         connectedPort = port;
 221     }
 222 
 223 
 224     /**
 225      * Constructs a datagram socket and binds it to any available port
 226      * on the local host machine.  The socket will be bound to the
 227      * {@link InetAddress#isAnyLocalAddress wildcard} address,
 228      * an IP address chosen by the kernel.
 229      *
 230      * <p>If there is a security manager,
 231      * its {@code checkListen} method is first called
 232      * with 0 as its argument to ensure the operation is allowed.
 233      * This could result in a SecurityException.
 234      *
 235      * @throws     SocketException  if the socket could not be opened,
 236      *               or the socket could not bind to the specified local port.
 237      * @throws     SecurityException  if a security manager exists and its
 238      *             {@code checkListen} method doesn't allow the operation.
 239      *
 240      * @see SecurityManager#checkListen
 241      */
 242     public DatagramSocket() throws SocketException {
 243         this(new InetSocketAddress(0));
 244     }
 245 
 246     /**
 247      * Creates an unbound datagram socket with the specified
 248      * DatagramSocketImpl.
 249      *
 250      * @param impl an instance of a <B>DatagramSocketImpl</B>
 251      *        the subclass wishes to use on the DatagramSocket.
 252      * @since   1.4
 253      */
 254     protected DatagramSocket(DatagramSocketImpl impl) {
 255         if (impl == null)
 256             throw new NullPointerException();
 257         this.impl = impl;
 258         checkOldImpl();
 259     }
 260 
 261     /**
 262      * Creates a datagram socket, bound to the specified local
 263      * socket address.
 264      * <p>
 265      * If, if the address is {@code null}, creates an unbound socket.
 266      *
 267      * <p>If there is a security manager,
 268      * its {@code checkListen} method is first called
 269      * with the port from the socket address
 270      * as its argument to ensure the operation is allowed.
 271      * This could result in a SecurityException.
 272      *
 273      * @param bindaddr local socket address to bind, or {@code null}
 274      *                 for an unbound socket.
 275      *
 276      * @throws     SocketException  if the socket could not be opened,
 277      *               or the socket could not bind to the specified local port.
 278      * @throws     SecurityException  if a security manager exists and its
 279      *             {@code checkListen} method doesn't allow the operation.
 280      *
 281      * @see SecurityManager#checkListen
 282      * @since   1.4
 283      */
 284     public DatagramSocket(SocketAddress bindaddr) throws SocketException {
 285         // create a datagram socket.
 286         createImpl();
 287         if (bindaddr != null) {
 288             try {
 289                 bind(bindaddr);
 290             } finally {
 291                 if (!isBound())
 292                     close();
 293             }
 294         }
 295     }
 296 
 297     /**
 298      * Constructs a datagram socket and binds it to the specified port
 299      * on the local host machine.  The socket will be bound to the
 300      * {@link InetAddress#isAnyLocalAddress wildcard} address,
 301      * an IP address chosen by the kernel.
 302      *
 303      * <p>If there is a security manager,
 304      * its {@code checkListen} method is first called
 305      * with the {@code port} argument
 306      * as its argument to ensure the operation is allowed.
 307      * This could result in a SecurityException.
 308      *
 309      * @param      port port to use.
 310      * @throws     SocketException  if the socket could not be opened,
 311      *               or the socket could not bind to the specified local port.
 312      * @throws     SecurityException  if a security manager exists and its
 313      *             {@code checkListen} method doesn't allow the operation.
 314      *
 315      * @see SecurityManager#checkListen
 316      */
 317     public DatagramSocket(int port) throws SocketException {
 318         this(port, null);
 319     }
 320 
 321     /**
 322      * Creates a datagram socket, bound to the specified local
 323      * address.  The local port must be between 0 and 65535 inclusive.
 324      * If the IP address is 0.0.0.0, the socket will be bound to the
 325      * {@link InetAddress#isAnyLocalAddress wildcard} address,
 326      * an IP address chosen by the kernel.
 327      *
 328      * <p>If there is a security manager,
 329      * its {@code checkListen} method is first called
 330      * with the {@code port} argument
 331      * as its argument to ensure the operation is allowed.
 332      * This could result in a SecurityException.
 333      *
 334      * @param port local port to use
 335      * @param laddr local address to bind
 336      *
 337      * @throws     SocketException  if the socket could not be opened,
 338      *               or the socket could not bind to the specified local port.
 339      * @throws     SecurityException  if a security manager exists and its
 340      *             {@code checkListen} method doesn't allow the operation.
 341      *
 342      * @see SecurityManager#checkListen
 343      * @since   1.1
 344      */
 345     public DatagramSocket(int port, InetAddress laddr) throws SocketException {
 346         this(new InetSocketAddress(laddr, port));
 347     }
 348 
 349     private void checkOldImpl() {
 350         if (impl == null)
 351             return;
 352         // DatagramSocketImpl.peekData() is a protected method, therefore we need to use
 353         // getDeclaredMethod, therefore we need permission to access the member
 354         try {
 355             AccessController.doPrivileged(
 356                 new PrivilegedExceptionAction<>() {
 357                     public Void run() throws NoSuchMethodException {
 358                         Class<?>[] cl = new Class<?>[1];
 359                         cl[0] = DatagramPacket.class;
 360                         impl.getClass().getDeclaredMethod("peekData", cl);
 361                         return null;
 362                     }
 363                 });
 364         } catch (java.security.PrivilegedActionException e) {
 365             oldImpl = true;
 366         }
 367     }
 368 
 369     static Class<?> implClass = null;
 370 
 371     void createImpl() throws SocketException {
 372         if (impl == null) {
 373             if (factory != null) {
 374                 impl = factory.createDatagramSocketImpl();
 375                 checkOldImpl();
 376             } else {
 377                 boolean isMulticast = (this instanceof MulticastSocket) ? true : false;
 378                 impl = DefaultDatagramSocketImplFactory.createDatagramSocketImpl(isMulticast);
 379 
 380                 checkOldImpl();
 381             }
 382         }
 383         // creates a udp socket
 384         impl.create();
 385         created = true;
 386     }
 387 
 388     /**
 389      * Get the {@code DatagramSocketImpl} attached to this socket,
 390      * creating it if necessary.
 391      *
 392      * @return  the {@code DatagramSocketImpl} attached to that
 393      *          DatagramSocket
 394      * @throws SocketException if creation fails.
 395      * @since 1.4
 396      */
 397     DatagramSocketImpl getImpl() throws SocketException {
 398         if (!created)
 399             createImpl();
 400         return impl;
 401     }
 402 
 403     /**
 404      * Binds this DatagramSocket to a specific address and port.
 405      * <p>
 406      * If the address is {@code null}, then the system will pick up
 407      * an ephemeral port and a valid local address to bind the socket.
 408      *
 409      * @param   addr The address and port to bind to.
 410      * @throws  SocketException if any error happens during the bind, or if the
 411      *          socket is already bound.
 412      * @throws  SecurityException  if a security manager exists and its
 413      *             {@code checkListen} method doesn't allow the operation.
 414      * @throws IllegalArgumentException if addr is a SocketAddress subclass
 415      *         not supported by this socket.
 416      * @since 1.4
 417      */
 418     public synchronized void bind(SocketAddress addr) throws SocketException {
 419         if (isClosed())
 420             throw new SocketException("Socket is closed");
 421         if (isBound())
 422             throw new SocketException("already bound");
 423         if (addr == null)
 424             addr = new InetSocketAddress(0);
 425         if (!(addr instanceof InetSocketAddress))
 426             throw new IllegalArgumentException("Unsupported address type!");
 427         InetSocketAddress epoint = (InetSocketAddress) addr;
 428         if (epoint.isUnresolved())
 429             throw new SocketException("Unresolved address");
 430         InetAddress iaddr = epoint.getAddress();
 431         int port = epoint.getPort();
 432         checkAddress(iaddr, "bind");
 433         SecurityManager sec = System.getSecurityManager();
 434         if (sec != null) {
 435             sec.checkListen(port);
 436         }
 437         try {
 438             getImpl().bind(port, iaddr);
 439         } catch (SocketException e) {
 440             getImpl().close();
 441             throw e;
 442         }
 443         bound = true;
 444     }
 445 
 446     void checkAddress (InetAddress addr, String op) {
 447         if (addr == null) {
 448             return;
 449         }
 450         if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
 451             throw new IllegalArgumentException(op + ": invalid address type");
 452         }
 453     }
 454 
 455     /**
 456      * Connects the socket to a remote address for this socket. When a
 457      * socket is connected to a remote address, packets may only be
 458      * sent to or received from that address. By default a datagram
 459      * socket is not connected.
 460      *
 461      * <p>If the remote destination to which the socket is connected does not
 462      * exist, or is otherwise unreachable, and if an ICMP destination unreachable
 463      * packet has been received for that address, then a subsequent call to
 464      * send or receive may throw a PortUnreachableException. Note, there is no
 465      * guarantee that the exception will be thrown.
 466      *
 467      * <p> If a security manager has been installed then it is invoked to check
 468      * access to the remote address. Specifically, if the given {@code address}
 469      * is a {@link InetAddress#isMulticastAddress multicast address},
 470      * the security manager's {@link
 471      * java.lang.SecurityManager#checkMulticast(InetAddress)
 472      * checkMulticast} method is invoked with the given {@code address}.
 473      * Otherwise, the security manager's {@link
 474      * java.lang.SecurityManager#checkConnect(String,int) checkConnect}
 475      * and {@link java.lang.SecurityManager#checkAccept checkAccept} methods
 476      * are invoked, with the given {@code address} and {@code port}, to
 477      * verify that datagrams are permitted to be sent and received
 478      * respectively.
 479      *
 480      * <p> Care should be taken to ensure that a connected datagram socket
 481      * is not shared with untrusted code. When a socket is connected,
 482      * {@link #receive receive} and {@link #send send} <b>will not perform
 483      * any security checks</b> on incoming and outgoing packets, other than
 484      * matching the packet's and the socket's address and port. On a send
 485      * operation, if the packet's address is set and the packet's address
 486      * and the socket's address do not match, an {@code IllegalArgumentException}
 487      * will be thrown. A socket connected to a multicast address may only
 488      * be used to send packets.
 489      *
 490      * @param address the remote address for the socket
 491      *
 492      * @param port the remote port for the socket.
 493      *
 494      * @throws IllegalArgumentException
 495      *         if the address is null, or the port is out of range.
 496      *
 497      * @throws SecurityException
 498      *         if a security manager has been installed and it does
 499      *         not permit access to the given remote address
 500      *




 501      * @see #disconnect
 502      */
 503     public void connect(InetAddress address, int port) {
 504         try {
 505             connectInternal(address, port);
 506         } catch (SocketException se) {
 507             throw new Error("connect failed", se);
 508         }
 509     }
 510 
 511     /**
 512      * Connects this socket to a remote socket address (IP address + port number).
 513      *
 514      * <p> If given an {@link InetSocketAddress InetSocketAddress}, this method
 515      * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)}
 516      * with the given socket addresses IP address and port number.
 517      *
 518      * @param   addr    The remote address.
 519      *
 520      * @throws  SocketException
 521      *          if the connect fails
 522      *
 523      * @throws IllegalArgumentException
 524      *         if {@code addr} is {@code null}, or {@code addr} is a SocketAddress
 525      *         subclass not supported by this socket
 526      *
 527      * @throws SecurityException
 528      *         if a security manager has been installed and it does
 529      *         not permit access to the given remote address
 530      *
 531      * @since 1.4
 532      */
 533     public void connect(SocketAddress addr) throws SocketException {
 534         if (addr == null)
 535             throw new IllegalArgumentException("Address can't be null");
 536         if (!(addr instanceof InetSocketAddress))
 537             throw new IllegalArgumentException("Unsupported address type");
 538         InetSocketAddress epoint = (InetSocketAddress) addr;
 539         if (epoint.isUnresolved())
 540             throw new SocketException("Unresolved address");
 541         connectInternal(epoint.getAddress(), epoint.getPort());
 542     }
 543 
 544     /**
 545      * Disconnects the socket. If the socket is closed or not connected,
 546      * then this method has no effect.
 547      *








 548      * @see #connect
 549      */
 550     public void disconnect() {
 551         synchronized (this) {
 552             if (isClosed())
 553                 return;
 554             if (connectState == ST_CONNECTED) {
 555                 impl.disconnect ();
 556             }
 557             connectedAddress = null;
 558             connectedPort = -1;
 559             connectState = ST_NOT_CONNECTED;
 560             explicitFilter = false;
 561         }
 562     }
 563 
 564     /**
 565      * Returns the binding state of the socket.
 566      * <p>
 567      * If the socket was bound prior to being {@link #close closed},
 568      * then this method will continue to return {@code true}
 569      * after the socket is closed.
 570      *
 571      * @return true if the socket successfully bound to an address
 572      * @since 1.4
 573      */
 574     public boolean isBound() {
 575         return bound;
 576     }
 577 
 578     /**
 579      * Returns the connection state of the socket.
 580      * <p>
 581      * If the socket was connected prior to being {@link #close closed},
 582      * then this method will continue to return {@code true}
 583      * after the socket is closed.
 584      *
 585      * @return true if the socket successfully connected to a server
 586      * @since 1.4
 587      */
 588     public boolean isConnected() {
 589         return connectState != ST_NOT_CONNECTED;
 590     }
 591 
 592     /**
 593      * Returns the address to which this socket is connected. Returns
 594      * {@code null} if the socket is not connected.
 595      * <p>
 596      * If the socket was connected prior to being {@link #close closed},
 597      * then this method will continue to return the connected address
 598      * after the socket is closed.
 599      *
 600      * @return the address to which this socket is connected.
 601      */
 602     public InetAddress getInetAddress() {
 603         return connectedAddress;
 604     }
 605 
 606     /**
 607      * Returns the port number to which this socket is connected.
 608      * Returns {@code -1} if the socket is not connected.
 609      * <p>
 610      * If the socket was connected prior to being {@link #close closed},
 611      * then this method will continue to return the connected port number
 612      * after the socket is closed.
 613      *
 614      * @return the port number to which this socket is connected.
 615      */
 616     public int getPort() {
 617         return connectedPort;
 618     }
 619 
 620     /**
 621      * Returns the address of the endpoint this socket is connected to, or
 622      * {@code null} if it is unconnected.
 623      * <p>
 624      * If the socket was connected prior to being {@link #close closed},
 625      * then this method will continue to return the connected address
 626      * after the socket is closed.
 627      *
 628      * @return a {@code SocketAddress} representing the remote
 629      *         endpoint of this socket, or {@code null} if it is
 630      *         not connected yet.
 631      * @see #getInetAddress()
 632      * @see #getPort()
 633      * @see #connect(SocketAddress)
 634      * @since 1.4
 635      */
 636     public SocketAddress getRemoteSocketAddress() {
 637         if (!isConnected())
 638             return null;
 639         return new InetSocketAddress(getInetAddress(), getPort());
 640     }
 641 
 642     /**
 643      * Returns the address of the endpoint this socket is bound to.
 644      *
 645      * @return a {@code SocketAddress} representing the local endpoint of this
 646      *         socket, or {@code null} if it is closed or not bound yet.
 647      * @see #getLocalAddress()
 648      * @see #getLocalPort()
 649      * @see #bind(SocketAddress)
 650      * @since 1.4
 651      */
 652     public SocketAddress getLocalSocketAddress() {
 653         if (isClosed())
 654             return null;
 655         if (!isBound())
 656             return null;
 657         return new InetSocketAddress(getLocalAddress(), getLocalPort());
 658     }
 659 
 660     /**
 661      * Sends a datagram packet from this socket. The
 662      * {@code DatagramPacket} includes information indicating the
 663      * data to be sent, its length, the IP address of the remote host,
 664      * and the port number on the remote host.
 665      *
 666      * <p>If there is a security manager, and the socket is not currently
 667      * connected to a remote address, this method first performs some
 668      * security checks. First, if {@code p.getAddress().isMulticastAddress()}
 669      * is true, this method calls the
 670      * security manager's {@code checkMulticast} method
 671      * with {@code p.getAddress()} as its argument.
 672      * If the evaluation of that expression is false,
 673      * this method instead calls the security manager's
 674      * {@code checkConnect} method with arguments
 675      * {@code p.getAddress().getHostAddress()} and
 676      * {@code p.getPort()}. Each call to a security manager method
 677      * could result in a SecurityException if the operation is not allowed.
 678      *
 679      * @param      p   the {@code DatagramPacket} to be sent.
 680      *
 681      * @throws     IOException  if an I/O error occurs.
 682      * @throws     SecurityException  if a security manager exists and its
 683      *             {@code checkMulticast} or {@code checkConnect}
 684      *             method doesn't allow the send.
 685      * @throws     PortUnreachableException may be thrown if the socket is connected
 686      *             to a currently unreachable destination. Note, there is no
 687      *             guarantee that the exception will be thrown.
 688      * @throws     java.nio.channels.IllegalBlockingModeException
 689      *             if this socket has an associated channel,
 690      *             and the channel is in non-blocking mode.
 691      * @throws     IllegalArgumentException if the socket is connected,
 692      *             and connected address and packet address differ, or
 693      *             if the socket is not connected and the packet address
 694      *             is not set.
 695      *
 696      * @see        java.net.DatagramPacket
 697      * @see        SecurityManager#checkMulticast(InetAddress)
 698      * @see        SecurityManager#checkConnect
 699      * @revised 1.4
 700      * @spec JSR-51
 701      */
 702     public void send(DatagramPacket p) throws IOException  {
 703         synchronized (p) {
 704             if (isClosed())
 705                 throw new SocketException("Socket is closed");
 706             InetAddress packetAddress = p.getAddress();
 707             checkAddress (packetAddress, "send");
 708             if (connectState == ST_NOT_CONNECTED) {
 709                 if (packetAddress == null) {
 710                     throw new IllegalArgumentException("Address not set");
 711                 }
 712                 // check the address is ok with the security manager on every send.
 713                 SecurityManager security = System.getSecurityManager();
 714 
 715                 // The reason you want to synchronize on datagram packet
 716                 // is because you don't want an applet to change the address
 717                 // while you are trying to send the packet for example
 718                 // after the security check but before the send.
 719                 if (security != null) {
 720                     if (packetAddress.isMulticastAddress()) {
 721                         security.checkMulticast(packetAddress);
 722                     } else {
 723                         security.checkConnect(packetAddress.getHostAddress(),
 724                                               p.getPort());
 725                     }
 726                 }
 727             } else {
 728                 // we're connected
 729                 if (packetAddress == null) {
 730                     p.setAddress(connectedAddress);
 731                     p.setPort(connectedPort);
 732                 } else if ((!packetAddress.equals(connectedAddress)) ||
 733                            p.getPort() != connectedPort) {
 734                     throw new IllegalArgumentException("connected address " +
 735                                                        "and packet address" +
 736                                                        " differ");
 737                 }
 738             }
 739             // Check whether the socket is bound
 740             if (!isBound())
 741                 bind(new InetSocketAddress(0));
 742             // call the  method to send
 743             getImpl().send(p);
 744         }
 745     }
 746 
 747     /**
 748      * Receives a datagram packet from this socket. When this method
 749      * returns, the {@code DatagramPacket}'s buffer is filled with
 750      * the data received. The datagram packet also contains the sender's
 751      * IP address, and the port number on the sender's machine.
 752      * <p>
 753      * This method blocks until a datagram is received. The
 754      * {@code length} field of the datagram packet object contains
 755      * the length of the received message. If the message is longer than
 756      * the packet's length, the message is truncated.
 757      * <p>
 758      * If there is a security manager, and the socket is not currently
 759      * connected to a remote address, a packet cannot be received if the
 760      * security manager's {@code checkAccept} method does not allow it.
 761      * Datagrams that are not permitted by the security manager are silently
 762      * discarded.
 763      *
 764      * @param      p   the {@code DatagramPacket} into which to place
 765      *                 the incoming data.
 766      * @throws     IOException  if an I/O error occurs.
 767      * @throws     SocketTimeoutException  if setSoTimeout was previously called
 768      *                 and the timeout has expired.
 769      * @throws     PortUnreachableException may be thrown if the socket is connected
 770      *             to a currently unreachable destination. Note, there is no guarantee that the
 771      *             exception will be thrown.
 772      * @throws     java.nio.channels.IllegalBlockingModeException
 773      *             if this socket has an associated channel,
 774      *             and the channel is in non-blocking mode.
 775      * @see        java.net.DatagramPacket
 776      * @see        java.net.DatagramSocket
 777      * @revised 1.4
 778      * @spec JSR-51
 779      */
 780     public synchronized void receive(DatagramPacket p) throws IOException {
 781         synchronized (p) {
 782             if (!isBound())
 783                 bind(new InetSocketAddress(0));
 784             if (connectState == ST_NOT_CONNECTED) {
 785                 // check the address is ok with the security manager before every recv.
 786                 SecurityManager security = System.getSecurityManager();
 787                 if (security != null) {
 788                     while(true) {
 789                         String peekAd = null;
 790                         int peekPort = 0;
 791                         // peek at the packet to see who it is from.
 792                         if (!oldImpl) {
 793                             // We can use the new peekData() API
 794                             DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
 795                             peekPort = getImpl().peekData(peekPacket);
 796                             peekAd = peekPacket.getAddress().getHostAddress();
 797                         } else {
 798                             InetAddress adr = new InetAddress();
 799                             peekPort = getImpl().peek(adr);
 800                             peekAd = adr.getHostAddress();
 801                         }
 802                         try {
 803                             security.checkAccept(peekAd, peekPort);
 804                             // security check succeeded - so now break
 805                             // and recv the packet.
 806                             break;
 807                         } catch (SecurityException se) {
 808                             // Throw away the offending packet by consuming
 809                             // it in a tmp buffer.
 810                             DatagramPacket tmp = new DatagramPacket(new byte[1], 1);
 811                             getImpl().receive(tmp);
 812 
 813                             // silently discard the offending packet
 814                             // and continue: unknown/malicious
 815                             // entities on nets should not make
 816                             // runtime throw security exception and
 817                             // disrupt the applet by sending random
 818                             // datagram packets.
 819                             continue;
 820                         }
 821                     } // end of while
 822                 }
 823             }
 824             DatagramPacket tmp = null;
 825             if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) {
 826                 // We have to do the filtering the old fashioned way since
 827                 // the native impl doesn't support connect or the connect
 828                 // via the impl failed, or .. "explicitFilter" may be set when
 829                 // a socket is connected via the impl, for a period of time
 830                 // when packets from other sources might be queued on socket.
 831                 boolean stop = false;
 832                 while (!stop) {
 833                     InetAddress peekAddress = null;
 834                     int peekPort = -1;
 835                     // peek at the packet to see who it is from.
 836                     if (!oldImpl) {
 837                         // We can use the new peekData() API
 838                         DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
 839                         peekPort = getImpl().peekData(peekPacket);
 840                         peekAddress = peekPacket.getAddress();
 841                     } else {
 842                         // this api only works for IPv4
 843                         peekAddress = new InetAddress();
 844                         peekPort = getImpl().peek(peekAddress);
 845                     }
 846                     if ((!connectedAddress.equals(peekAddress)) ||
 847                         (connectedPort != peekPort)) {
 848                         // throw the packet away and silently continue
 849                         tmp = new DatagramPacket(
 850                                                 new byte[1024], 1024);
 851                         getImpl().receive(tmp);
 852                         if (explicitFilter) {
 853                             if (checkFiltering(tmp)) {
 854                                 stop = true;
 855                             }
 856                         }
 857                     } else {
 858                         stop = true;
 859                     }
 860                 }
 861             }
 862             // If the security check succeeds, or the datagram is
 863             // connected then receive the packet
 864             getImpl().receive(p);
 865             if (explicitFilter && tmp == null) {
 866                 // packet was not filtered, account for it here
 867                 checkFiltering(p);
 868             }
 869         }
 870     }
 871 
 872     private boolean checkFiltering(DatagramPacket p) throws SocketException {
 873         bytesLeftToFilter -= p.getLength();
 874         if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) {
 875             explicitFilter = false;
 876             return true;
 877         }
 878         return false;
 879     }
 880 
 881     /**
 882      * Gets the local address to which the socket is bound.
 883      *
 884      * <p>If there is a security manager, its
 885      * {@code checkConnect} method is first called
 886      * with the host address and {@code -1}
 887      * as its arguments to see if the operation is allowed.
 888      *
 889      * @see SecurityManager#checkConnect
 890      * @return  the local address to which the socket is bound,
 891      *          {@code null} if the socket is closed, or
 892      *          an {@code InetAddress} representing
 893      *          {@link InetAddress#isAnyLocalAddress wildcard}
 894      *          address if either the socket is not bound, or
 895      *          the security manager {@code checkConnect}
 896      *          method does not allow the operation
 897      * @since   1.1
 898      */
 899     public InetAddress getLocalAddress() {
 900         if (isClosed())
 901             return null;
 902         InetAddress in;
 903         try {
 904             in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
 905             if (in.isAnyLocalAddress()) {
 906                 in = InetAddress.anyLocalAddress();
 907             }
 908             SecurityManager s = System.getSecurityManager();
 909             if (s != null) {
 910                 s.checkConnect(in.getHostAddress(), -1);
 911             }
 912         } catch (Exception e) {
 913             in = InetAddress.anyLocalAddress(); // "0.0.0.0"
 914         }
 915         return in;
 916     }
 917 
 918     /**
 919      * Returns the port number on the local host to which this socket
 920      * is bound.
 921      *
 922      * @return  the port number on the local host to which this socket is bound,
 923      *          {@code -1} if the socket is closed, or
 924      *          {@code 0} if it is not bound yet.
 925      */
 926     public int getLocalPort() {
 927         if (isClosed())
 928             return -1;
 929         try {
 930             return getImpl().getLocalPort();
 931         } catch (Exception e) {
 932             return 0;
 933         }
 934     }
 935 
 936     /**
 937      * Enable/disable SO_TIMEOUT with the specified timeout, in
 938      * milliseconds. With this option set to a positive timeout value,
 939      * a call to receive() for this DatagramSocket
 940      * will block for only this amount of time.  If the timeout expires,
 941      * a <B>java.net.SocketTimeoutException</B> is raised, though the
 942      * DatagramSocket is still valid. A timeout of zero is interpreted
 943      * as an infinite timeout.
 944      * The option <B>must</B> be enabled prior to entering the blocking
 945      * operation to have effect.
 946      *
 947      * @param timeout the specified timeout in milliseconds.
 948      * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
 949      * @throws IllegalArgumentException if {@code timeout} is negative
 950      * @since   1.1
 951      * @see #getSoTimeout()
 952      */
 953     public synchronized void setSoTimeout(int timeout) throws SocketException {
 954         if (isClosed())
 955             throw new SocketException("Socket is closed");
 956         if (timeout < 0)
 957             throw new IllegalArgumentException("timeout < 0");
 958         getImpl().setOption(SocketOptions.SO_TIMEOUT, timeout);
 959     }
 960 
 961     /**
 962      * Retrieve setting for SO_TIMEOUT.  0 returns implies that the
 963      * option is disabled (i.e., timeout of infinity).
 964      *
 965      * @return the setting for SO_TIMEOUT
 966      * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
 967      * @since   1.1
 968      * @see #setSoTimeout(int)
 969      */
 970     public synchronized int getSoTimeout() throws SocketException {
 971         if (isClosed())
 972             throw new SocketException("Socket is closed");
 973         if (getImpl() == null)
 974             return 0;
 975         Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
 976         /* extra type safety */
 977         if (o instanceof Integer) {
 978             return ((Integer) o).intValue();
 979         } else {
 980             return 0;
 981         }
 982     }
 983 
 984     /**
 985      * Sets the SO_SNDBUF option to the specified value for this
 986      * {@code DatagramSocket}. The SO_SNDBUF option is used by the
 987      * network implementation as a hint to size the underlying
 988      * network I/O buffers. The SO_SNDBUF setting may also be used
 989      * by the network implementation to determine the maximum size
 990      * of the packet that can be sent on this socket.
 991      * <p>
 992      * As SO_SNDBUF is a hint, applications that want to verify
 993      * what size the buffer is should call {@link #getSendBufferSize()}.
 994      * <p>
 995      * Increasing the buffer size may allow multiple outgoing packets
 996      * to be queued by the network implementation when the send rate
 997      * is high.
 998      * <p>
 999      * Note: If {@link #send(DatagramPacket)} is used to send a
1000      * {@code DatagramPacket} that is larger than the setting
1001      * of SO_SNDBUF then it is implementation specific if the
1002      * packet is sent or discarded.
1003      *
1004      * @param size the size to which to set the send buffer
1005      * size. This value must be greater than 0.
1006      *
1007      * @throws    SocketException if there is an error
1008      * in the underlying protocol, such as an UDP error.
1009      * @throws    IllegalArgumentException if the value is 0 or is
1010      * negative.
1011      * @see #getSendBufferSize()
1012      */
1013     public synchronized void setSendBufferSize(int size) throws SocketException {
1014         if (!(size > 0)) {
1015             throw new IllegalArgumentException("negative send size");
1016         }
1017         if (isClosed())
1018             throw new SocketException("Socket is closed");
1019         getImpl().setOption(SocketOptions.SO_SNDBUF, size);
1020     }
1021 
1022     /**
1023      * Get value of the SO_SNDBUF option for this {@code DatagramSocket}, that is the
1024      * buffer size used by the platform for output on this {@code DatagramSocket}.
1025      *
1026      * @return the value of the SO_SNDBUF option for this {@code DatagramSocket}
1027      * @throws    SocketException if there is an error in
1028      * the underlying protocol, such as an UDP error.
1029      * @see #setSendBufferSize
1030      */
1031     public synchronized int getSendBufferSize() throws SocketException {
1032         if (isClosed())
1033             throw new SocketException("Socket is closed");
1034         int result = 0;
1035         Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
1036         if (o instanceof Integer) {
1037             result = ((Integer)o).intValue();
1038         }
1039         return result;
1040     }
1041 
1042     /**
1043      * Sets the SO_RCVBUF option to the specified value for this
1044      * {@code DatagramSocket}. The SO_RCVBUF option is used by
1045      * the network implementation as a hint to size the underlying
1046      * network I/O buffers. The SO_RCVBUF setting may also be used
1047      * by the network implementation to determine the maximum size
1048      * of the packet that can be received on this socket.
1049      * <p>
1050      * Because SO_RCVBUF is a hint, applications that want to
1051      * verify what size the buffers were set to should call
1052      * {@link #getReceiveBufferSize()}.
1053      * <p>
1054      * Increasing SO_RCVBUF may allow the network implementation
1055      * to buffer multiple packets when packets arrive faster than
1056      * are being received using {@link #receive(DatagramPacket)}.
1057      * <p>
1058      * Note: It is implementation specific if a packet larger
1059      * than SO_RCVBUF can be received.
1060      *
1061      * @param size the size to which to set the receive buffer
1062      * size. This value must be greater than 0.
1063      *
1064      * @throws    SocketException if there is an error in
1065      * the underlying protocol, such as an UDP error.
1066      * @throws    IllegalArgumentException if the value is 0 or is
1067      * negative.
1068      * @see #getReceiveBufferSize()
1069      */
1070     public synchronized void setReceiveBufferSize(int size) throws SocketException {
1071         if (size <= 0) {
1072             throw new IllegalArgumentException("invalid receive size");
1073         }
1074         if (isClosed())
1075             throw new SocketException("Socket is closed");
1076         getImpl().setOption(SocketOptions.SO_RCVBUF, size);
1077     }
1078 
1079     /**
1080      * Get value of the SO_RCVBUF option for this {@code DatagramSocket}, that is the
1081      * buffer size used by the platform for input on this {@code DatagramSocket}.
1082      *
1083      * @return the value of the SO_RCVBUF option for this {@code DatagramSocket}
1084      * @throws    SocketException if there is an error in the underlying protocol, such as an UDP error.
1085      * @see #setReceiveBufferSize(int)
1086      */
1087     public synchronized int getReceiveBufferSize() throws SocketException {
1088         if (isClosed())
1089             throw new SocketException("Socket is closed");
1090         int result = 0;
1091         Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
1092         if (o instanceof Integer) {
1093             result = ((Integer)o).intValue();
1094         }
1095         return result;
1096     }
1097 
1098     /**
1099      * Enable/disable the SO_REUSEADDR socket option.
1100      * <p>
1101      * For UDP sockets it may be necessary to bind more than one
1102      * socket to the same socket address. This is typically for the
1103      * purpose of receiving multicast packets
1104      * (See {@link java.net.MulticastSocket}). The
1105      * {@code SO_REUSEADDR} socket option allows multiple
1106      * sockets to be bound to the same socket address if the
1107      * {@code SO_REUSEADDR} socket option is enabled prior
1108      * to binding the socket using {@link #bind(SocketAddress)}.
1109      * <p>
1110      * Note: This functionality is not supported by all existing platforms,
1111      * so it is implementation specific whether this option will be ignored
1112      * or not. However, if it is not supported then
1113      * {@link #getReuseAddress()} will always return {@code false}.
1114      * <p>
1115      * When a {@code DatagramSocket} is created the initial setting
1116      * of {@code SO_REUSEADDR} is disabled.
1117      * <p>
1118      * The behaviour when {@code SO_REUSEADDR} is enabled or
1119      * disabled after a socket is bound (See {@link #isBound()})
1120      * is not defined.
1121      *
1122      * @param on  whether to enable or disable the
1123      * @throws    SocketException if an error occurs enabling or
1124      *            disabling the {@code SO_REUSEADDR} socket option,
1125      *            or the socket is closed.
1126      * @since 1.4
1127      * @see #getReuseAddress()
1128      * @see #bind(SocketAddress)
1129      * @see #isBound()
1130      * @see #isClosed()
1131      */
1132     public synchronized void setReuseAddress(boolean on) throws SocketException {
1133         if (isClosed())
1134             throw new SocketException("Socket is closed");
1135         // Integer instead of Boolean for compatibility with older DatagramSocketImpl
1136         if (oldImpl)
1137             getImpl().setOption(SocketOptions.SO_REUSEADDR, on?-1:0);
1138         else
1139             getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
1140     }
1141 
1142     /**
1143      * Tests if SO_REUSEADDR is enabled.
1144      *
1145      * @return a {@code boolean} indicating whether or not SO_REUSEADDR is enabled.
1146      * @throws    SocketException if there is an error
1147      * in the underlying protocol, such as an UDP error.
1148      * @since   1.4
1149      * @see #setReuseAddress(boolean)
1150      */
1151     public synchronized boolean getReuseAddress() throws SocketException {
1152         if (isClosed())
1153             throw new SocketException("Socket is closed");
1154         Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR);
1155         return ((Boolean)o).booleanValue();
1156     }
1157 
1158     /**
1159      * Enable/disable SO_BROADCAST.
1160      *
1161      * <p> Some operating systems may require that the Java virtual machine be
1162      * started with implementation specific privileges to enable this option or
1163      * send broadcast datagrams.
1164      *
1165      * @param  on
1166      *         whether or not to have broadcast turned on.
1167      *
1168      * @throws  SocketException
1169      *          if there is an error in the underlying protocol, such as an UDP
1170      *          error.
1171      *
1172      * @since 1.4
1173      * @see #getBroadcast()
1174      */
1175     public synchronized void setBroadcast(boolean on) throws SocketException {
1176         if (isClosed())
1177             throw new SocketException("Socket is closed");
1178         getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(on));
1179     }
1180 
1181     /**
1182      * Tests if SO_BROADCAST is enabled.
1183      * @return a {@code boolean} indicating whether or not SO_BROADCAST is enabled.
1184      * @throws    SocketException if there is an error
1185      * in the underlying protocol, such as an UDP error.
1186      * @since 1.4
1187      * @see #setBroadcast(boolean)
1188      */
1189     public synchronized boolean getBroadcast() throws SocketException {
1190         if (isClosed())
1191             throw new SocketException("Socket is closed");
1192         return ((Boolean)(getImpl().getOption(SocketOptions.SO_BROADCAST))).booleanValue();
1193     }
1194 
1195     /**
1196      * Sets traffic class or type-of-service octet in the IP
1197      * datagram header for datagrams sent from this DatagramSocket.
1198      * As the underlying network implementation may ignore this
1199      * value applications should consider it a hint.
1200      *
1201      * <P> The tc <B>must</B> be in the range {@code 0 <= tc <=
1202      * 255} or an IllegalArgumentException will be thrown.
1203      * <p>Notes:
1204      * <p>For Internet Protocol v4 the value consists of an
1205      * {@code integer}, the least significant 8 bits of which
1206      * represent the value of the TOS octet in IP packets sent by
1207      * the socket.
1208      * RFC 1349 defines the TOS values as follows:
1209      *
1210      * <UL>
1211      * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
1212      * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
1213      * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
1214      * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
1215      * </UL>
1216      * The last low order bit is always ignored as this
1217      * corresponds to the MBZ (must be zero) bit.
1218      * <p>
1219      * Setting bits in the precedence field may result in a
1220      * SocketException indicating that the operation is not
1221      * permitted.
1222      * <p>
1223      * for Internet Protocol v6 {@code tc} is the value that
1224      * would be placed into the sin6_flowinfo field of the IP header.
1225      *
1226      * @param tc        an {@code int} value for the bitset.
1227      * @throws SocketException if there is an error setting the
1228      * traffic class or type-of-service
1229      * @since 1.4
1230      * @see #getTrafficClass
1231      */
1232     public synchronized void setTrafficClass(int tc) throws SocketException {
1233         if (tc < 0 || tc > 255)
1234             throw new IllegalArgumentException("tc is not in range 0 -- 255");
1235 
1236         if (isClosed())
1237             throw new SocketException("Socket is closed");
1238         try {
1239             getImpl().setOption(SocketOptions.IP_TOS, tc);
1240         } catch (SocketException se) {
1241             // not supported if socket already connected
1242             // Solaris returns error in such cases
1243             if(!isConnected())
1244                 throw se;
1245         }
1246     }
1247 
1248     /**
1249      * Gets traffic class or type-of-service in the IP datagram
1250      * header for packets sent from this DatagramSocket.
1251      * <p>
1252      * As the underlying network implementation may ignore the
1253      * traffic class or type-of-service set using {@link #setTrafficClass(int)}
1254      * this method may return a different value than was previously
1255      * set using the {@link #setTrafficClass(int)} method on this
1256      * DatagramSocket.
1257      *
1258      * @return the traffic class or type-of-service already set
1259      * @throws SocketException if there is an error obtaining the
1260      * traffic class or type-of-service value.
1261      * @since 1.4
1262      * @see #setTrafficClass(int)
1263      */
1264     public synchronized int getTrafficClass() throws SocketException {
1265         if (isClosed())
1266             throw new SocketException("Socket is closed");
1267         return ((Integer)(getImpl().getOption(SocketOptions.IP_TOS))).intValue();
1268     }
1269 
1270     /**
1271      * Closes this datagram socket.
1272      * <p>
1273      * Any thread currently blocked in {@link #receive} upon this socket
1274      * will throw a {@link SocketException}.
1275      *
1276      * <p> If this socket has an associated channel then the channel is closed
1277      * as well.
1278      *
1279      * @revised 1.4
1280      * @spec JSR-51
1281      */
1282     public void close() {
1283         synchronized(closeLock) {
1284             if (isClosed())
1285                 return;
1286             impl.close();
1287             closed = true;
1288         }
1289     }
1290 
1291     /**
1292      * Returns whether the socket is closed or not.
1293      *
1294      * @return true if the socket has been closed
1295      * @since 1.4
1296      */
1297     public boolean isClosed() {
1298         synchronized(closeLock) {
1299             return closed;
1300         }
1301     }
1302 
1303     /**
1304      * Returns the unique {@link java.nio.channels.DatagramChannel} object
1305      * associated with this datagram socket, if any.
1306      *
1307      * <p> A datagram socket will have a channel if, and only if, the channel
1308      * itself was created via the {@link java.nio.channels.DatagramChannel#open
1309      * DatagramChannel.open} method.
1310      *
1311      * @return  the datagram channel associated with this datagram socket,
1312      *          or {@code null} if this socket was not created for a channel
1313      *
1314      * @since 1.4
1315      * @spec JSR-51
1316      */
1317     public DatagramChannel getChannel() {
1318         return null;
1319     }
1320 
1321     /**
1322      * User defined factory for all datagram sockets.
1323      */
1324     static DatagramSocketImplFactory factory;
1325 
1326     /**
1327      * Sets the datagram socket implementation factory for the
1328      * application. The factory can be specified only once.
1329      * <p>
1330      * When an application creates a new datagram socket, the socket
1331      * implementation factory's {@code createDatagramSocketImpl} method is
1332      * called to create the actual datagram socket implementation.
1333      * <p>
1334      * Passing {@code null} to the method is a no-op unless the factory
1335      * was already set.
1336      *
1337      * <p>If there is a security manager, this method first calls
1338      * the security manager's {@code checkSetFactory} method
1339      * to ensure the operation is allowed.
1340      * This could result in a SecurityException.
1341      *
1342      * @param      fac   the desired factory.
1343      * @throws     IOException  if an I/O error occurs when setting the
1344      *              datagram socket factory.
1345      * @throws     SocketException  if the factory is already defined.
1346      * @throws     SecurityException  if a security manager exists and its
1347      *             {@code checkSetFactory} method doesn't allow the operation.
1348      * @see       java.net.DatagramSocketImplFactory#createDatagramSocketImpl()
1349      * @see       SecurityManager#checkSetFactory
1350      * @since 1.3
1351      */
1352     public static synchronized void
1353     setDatagramSocketImplFactory(DatagramSocketImplFactory fac)
1354        throws IOException
1355     {
1356         if (factory != null) {
1357             throw new SocketException("factory already defined");
1358         }
1359         SecurityManager security = System.getSecurityManager();
1360         if (security != null) {
1361             security.checkSetFactory();
1362         }
1363         factory = fac;
1364     }
1365 
1366     /**
1367      * Sets the value of a socket option.
1368      *
1369      * @param <T> The type of the socket option value
1370      * @param name The socket option
1371      * @param value The value of the socket option. A value of {@code null}
1372      *              may be valid for some options.
1373      *
1374      * @return this DatagramSocket
1375      *
1376      * @throws UnsupportedOperationException if the datagram socket
1377      *         does not support the option.
1378      *
1379      * @throws IllegalArgumentException if the value is not valid for
1380      *         the option.
1381      *
1382      * @throws IOException if an I/O error occurs, or if the socket is closed.
1383      *
1384      * @throws SecurityException if a security manager is set and if the socket
1385      *         option requires a security permission and if the caller does
1386      *         not have the required permission.
1387      *         {@link java.net.StandardSocketOptions StandardSocketOptions}
1388      *         do not require any security permission.
1389      *
1390      * @throws NullPointerException if name is {@code null}
1391      *
1392      * @since 9
1393      */
1394     public <T> DatagramSocket setOption(SocketOption<T> name, T value)
1395         throws IOException
1396     {
1397         Objects.requireNonNull(name);
1398         if (isClosed())
1399             throw new SocketException("Socket is closed");
1400         getImpl().setOption(name, value);
1401         return this;
1402     }
1403 
1404     /**
1405      * Returns the value of a socket option.
1406      *
1407      * @param <T> The type of the socket option value
1408      * @param name The socket option
1409      *
1410      * @return The value of the socket option.
1411      *
1412      * @throws UnsupportedOperationException if the datagram socket
1413      *         does not support the option.
1414      *
1415      * @throws IOException if an I/O error occurs, or if the socket is closed.
1416      *
1417      * @throws NullPointerException if name is {@code null}
1418      *
1419      * @throws SecurityException if a security manager is set and if the socket
1420      *         option requires a security permission and if the caller does
1421      *         not have the required permission.
1422      *         {@link java.net.StandardSocketOptions StandardSocketOptions}
1423      *         do not require any security permission.
1424      *
1425      * @since 9
1426      */
1427     public <T> T getOption(SocketOption<T> name) throws IOException {
1428         Objects.requireNonNull(name);
1429         if (isClosed())
1430             throw new SocketException("Socket is closed");
1431         return getImpl().getOption(name);
1432     }
1433 
1434     private static Set<SocketOption<?>> options;
1435     private static boolean optionsSet = false;
1436 
1437     /**
1438      * Returns a set of the socket options supported by this socket.
1439      *
1440      * This method will continue to return the set of options even after
1441      * the socket has been closed.
1442      *
1443      * @return A set of the socket options supported by this socket. This set
1444      *        may be empty if the socket's DatagramSocketImpl cannot be created.
1445      *
1446      * @since 9
1447      */
1448     public Set<SocketOption<?>> supportedOptions() {
1449         synchronized(DatagramSocket.class) {
1450             if (optionsSet) {
1451                 return options;
1452             }
1453             try {
1454                 DatagramSocketImpl impl = getImpl();
1455                 options = Collections.unmodifiableSet(impl.supportedOptions());
1456             } catch (IOException e) {
1457                 options = Collections.emptySet();
1458             }
1459             optionsSet = true;
1460             return options;
1461         }
1462     }
1463 }
--- EOF ---