1 /*
   2  * Copyright (c) 1995, 2020, 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 bound = false;
 120     private boolean closed = false;
 121     private volatile boolean created;
 122     private final Object closeLock = new Object();
 123 
 124     /*
 125      * The implementation of this DatagramSocket.
 126      */
 127     private final DatagramSocketImpl impl;
 128 
 129     /**
 130      * Are we using an older DatagramSocketImpl?
 131      */
 132     final boolean oldImpl;
 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         this.oldImpl = checkOldImpl(impl);
 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         // Special case initialization for the DatagramChannel socket adaptor.
 287         if (this instanceof sun.nio.ch.DatagramSocketAdaptor) {
 288             this.impl = null;  // no DatagramSocketImpl
 289             this.oldImpl = false;
 290             return;
 291         }
 292 
 293         // create a datagram socket.
 294         boolean multicast = (this instanceof MulticastSocket);
 295         this.impl = createImpl(multicast);
 296         // creates the udp socket
 297         impl.create();
 298         created = true;
 299         this.oldImpl = checkOldImpl(impl);
 300         if (bindaddr != null) {
 301             try {
 302                 bind(bindaddr);
 303             } finally {
 304                 if (!isBound())
 305                     close();
 306             }
 307         }
 308     }
 309 
 310     /**
 311      * Constructs a datagram socket and binds it to the specified port
 312      * on the local host machine.  The socket will be bound to the
 313      * {@link InetAddress#isAnyLocalAddress wildcard} address,
 314      * an IP address chosen by the kernel.
 315      *
 316      * <p>If there is a security manager,
 317      * its {@code checkListen} method is first called
 318      * with the {@code port} argument
 319      * as its argument to ensure the operation is allowed.
 320      * This could result in a SecurityException.
 321      *
 322      * @param      port port to use.
 323      * @throws     SocketException  if the socket could not be opened,
 324      *               or the socket could not bind to the specified local port.
 325      * @throws     SecurityException  if a security manager exists and its
 326      *             {@code checkListen} method doesn't allow the operation.
 327      *
 328      * @see SecurityManager#checkListen
 329      */
 330     public DatagramSocket(int port) throws SocketException {
 331         this(port, null);
 332     }
 333 
 334     /**
 335      * Creates a datagram socket, bound to the specified local
 336      * address.  The local port must be between 0 and 65535 inclusive.
 337      * If the IP address is 0.0.0.0, the socket will be bound to the
 338      * {@link InetAddress#isAnyLocalAddress wildcard} address,
 339      * an IP address chosen by the kernel.
 340      *
 341      * <p>If there is a security manager,
 342      * its {@code checkListen} method is first called
 343      * with the {@code port} argument
 344      * as its argument to ensure the operation is allowed.
 345      * This could result in a SecurityException.
 346      *
 347      * @param port local port to use
 348      * @param laddr local address to bind
 349      *
 350      * @throws     SocketException  if the socket could not be opened,
 351      *               or the socket could not bind to the specified local port.
 352      * @throws     SecurityException  if a security manager exists and its
 353      *             {@code checkListen} method doesn't allow the operation.
 354      *
 355      * @see SecurityManager#checkListen
 356      * @since   1.1
 357      */
 358     public DatagramSocket(int port, InetAddress laddr) throws SocketException {
 359         this(new InetSocketAddress(laddr, port));
 360     }
 361 
 362     /**
 363      * Return true if the given DatagramSocketImpl is an "old" impl. An old impl
 364      * is one that doesn't implement the abstract methods added in Java SE 1.4.
 365      */
 366     private static boolean checkOldImpl(DatagramSocketImpl impl) {
 367         // DatagramSocketImpl.peekData() is a protected method, therefore we need to use
 368         // getDeclaredMethod, therefore we need permission to access the member
 369         try {
 370             AccessController.doPrivileged(
 371                 new PrivilegedExceptionAction<>() {
 372                     public Void run() throws NoSuchMethodException {
 373                         Class<?>[] cl = new Class<?>[1];
 374                         cl[0] = DatagramPacket.class;
 375                         impl.getClass().getDeclaredMethod("peekData", cl);
 376                         return null;
 377                     }
 378                 });
 379             return false;
 380         } catch (java.security.PrivilegedActionException e) {
 381             return true;
 382         }
 383     }
 384 
 385     static Class<?> implClass = null;
 386 
 387     /**
 388      * Creates a DatagramSocketImpl.
 389      * @param multicast true if the DatagramSocketImpl is for a MulticastSocket
 390      */
 391     private static DatagramSocketImpl createImpl(boolean multicast) throws SocketException {
 392         DatagramSocketImpl impl;
 393         DatagramSocketImplFactory factory = DatagramSocket.factory;
 394         if (factory != null) {
 395             impl = factory.createDatagramSocketImpl();
 396         } else {
 397             impl = DefaultDatagramSocketImplFactory.createDatagramSocketImpl(multicast);
 398         }
 399         return impl;
 400     }
 401 
 402     /**
 403      * Return the {@code DatagramSocketImpl} attached to this socket,
 404      * creating the socket if not already created.
 405      *
 406      * @return  the {@code DatagramSocketImpl} attached to that
 407      *          DatagramSocket
 408      * @throws SocketException if creating the socket fails
 409      * @since 1.4
 410      */
 411     final DatagramSocketImpl getImpl() throws SocketException {
 412         if (!created) {
 413             synchronized (this) {
 414                 if (!created)  {
 415                     impl.create();
 416                     created = true;
 417                 }
 418             }
 419         }
 420         return impl;
 421     }
 422 
 423     /**
 424      * Binds this DatagramSocket to a specific address and port.
 425      * <p>
 426      * If the address is {@code null}, then the system will pick up
 427      * an ephemeral port and a valid local address to bind the socket.
 428      *
 429      * @param   addr The address and port to bind to.
 430      * @throws  SocketException if any error happens during the bind, or if the
 431      *          socket is already bound.
 432      * @throws  SecurityException  if a security manager exists and its
 433      *             {@code checkListen} method doesn't allow the operation.
 434      * @throws IllegalArgumentException if addr is a SocketAddress subclass
 435      *         not supported by this socket.
 436      * @since 1.4
 437      */
 438     public synchronized void bind(SocketAddress addr) throws SocketException {
 439         if (isClosed())
 440             throw new SocketException("Socket is closed");
 441         if (isBound())
 442             throw new SocketException("already bound");
 443         if (addr == null)
 444             addr = new InetSocketAddress(0);
 445         if (!(addr instanceof InetSocketAddress))
 446             throw new IllegalArgumentException("Unsupported address type!");
 447         InetSocketAddress epoint = (InetSocketAddress) addr;
 448         if (epoint.isUnresolved())
 449             throw new SocketException("Unresolved address");
 450         InetAddress iaddr = epoint.getAddress();
 451         int port = epoint.getPort();
 452         checkAddress(iaddr, "bind");
 453         SecurityManager sec = System.getSecurityManager();
 454         if (sec != null) {
 455             sec.checkListen(port);
 456         }
 457         try {
 458             getImpl().bind(port, iaddr);
 459         } catch (SocketException e) {
 460             getImpl().close();
 461             throw e;
 462         }
 463         bound = true;
 464     }
 465 
 466     void checkAddress (InetAddress addr, String op) {
 467         if (addr == null) {
 468             return;
 469         }
 470         if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
 471             throw new IllegalArgumentException(op + ": invalid address type");
 472         }
 473     }
 474 
 475     /**
 476      * Connects the socket to a remote address for this socket. When a
 477      * socket is connected to a remote address, packets may only be
 478      * sent to or received from that address. By default a datagram
 479      * socket is not connected. If the socket is already closed,
 480      * then this method has no effect.
 481      *
 482      * <p> If this socket is not bound then this method will first cause the
 483      * socket to be bound to an address that is assigned automatically,
 484      * as if invoking the {@link #bind bind} method with a parameter of
 485      * {@code null}. If the remote destination to which the socket is connected
 486      * does not exist, or is otherwise unreachable, and if an ICMP destination
 487      * unreachable packet has been received for that address, then a subsequent
 488      * call to send or receive may throw a PortUnreachableException. Note,
 489      * there is no guarantee that the exception will be thrown.
 490      *
 491      * <p> If a security manager has been installed then it is invoked to check
 492      * access to the remote address. Specifically, if the given {@code address}
 493      * is a {@link InetAddress#isMulticastAddress multicast address},
 494      * the security manager's {@link
 495      * java.lang.SecurityManager#checkMulticast(InetAddress)
 496      * checkMulticast} method is invoked with the given {@code address}.
 497      * Otherwise, the security manager's {@link
 498      * java.lang.SecurityManager#checkConnect(String,int) checkConnect}
 499      * and {@link java.lang.SecurityManager#checkAccept checkAccept} methods
 500      * are invoked, with the given {@code address} and {@code port}, to
 501      * verify that datagrams are permitted to be sent and received
 502      * respectively.
 503      *
 504      * <p> Care should be taken to ensure that a connected datagram socket
 505      * is not shared with untrusted code. When a socket is connected,
 506      * {@link #receive receive} and {@link #send send} <b>will not perform
 507      * any security checks</b> on incoming and outgoing packets, other than
 508      * matching the packet's and the socket's address and port. On a send
 509      * operation, if the packet's address is set and the packet's address
 510      * and the socket's address do not match, an {@code IllegalArgumentException}
 511      * will be thrown. A socket connected to a multicast address may only
 512      * be used to send packets.
 513      *
 514      * @param address the remote address for the socket
 515      *
 516      * @param port the remote port for the socket.
 517      *
 518      * @throws IllegalArgumentException
 519      *         if the address is null, or the port is out of range.
 520      *
 521      * @throws SecurityException
 522      *         if a security manager has been installed and it does
 523      *         not permit access to the given remote address
 524      *
 525      * @throws UncheckedIOException
 526      *         may be thrown if connect fails, for example, if the
 527      *         destination address is non-routable
 528      *
 529      * @see #disconnect
 530      *
 531      * @since 1.2
 532      */
 533     public void connect(InetAddress address, int port) {
 534         try {
 535             connectInternal(address, port);
 536         } catch (SocketException se) {
 537             throw new UncheckedIOException("connect failed", se);
 538         }
 539     }
 540 
 541     /**
 542      * Connects this socket to a remote socket address (IP address + port number).
 543      *
 544      * <p> If given an {@link InetSocketAddress InetSocketAddress}, this method
 545      * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)}
 546      * with the given socket addresses IP address and port number, except that the
 547      * {@code SocketException} that may be raised is not wrapped in an
 548      * {@code UncheckedIOException}.
 549      *
 550      * @param   addr    The remote address.
 551      *
 552      * @throws  SocketException
 553      *          if the connect fails
 554      *
 555      * @throws IllegalArgumentException
 556      *         if {@code addr} is {@code null}, or {@code addr} is a SocketAddress
 557      *         subclass not supported by this socket
 558      *
 559      * @throws SecurityException
 560      *         if a security manager has been installed and it does
 561      *         not permit access to the given remote address
 562      *
 563      * @since 1.4
 564      */
 565     public void connect(SocketAddress addr) throws SocketException {
 566         if (addr == null)
 567             throw new IllegalArgumentException("Address can't be null");
 568         if (!(addr instanceof InetSocketAddress))
 569             throw new IllegalArgumentException("Unsupported address type");
 570         InetSocketAddress epoint = (InetSocketAddress) addr;
 571         if (epoint.isUnresolved())
 572             throw new SocketException("Unresolved address");
 573         connectInternal(epoint.getAddress(), epoint.getPort());
 574     }
 575 
 576     /**
 577      * Disconnects the socket. If the socket is closed or not connected,
 578      * then this method has no effect.
 579      *
 580      * @apiNote If this method throws an UncheckedIOException, the socket
 581      *          may be left in an unspecified state. It is strongly
 582      *          recommended that the socket be closed when disconnect
 583      *          fails.
 584      *
 585      * @throws  UncheckedIOException
 586      *          may be thrown if disconnect fails to dissolve the
 587      *          association and restore the socket to a consistent state.
 588      *
 589      * @see #connect
 590      *
 591      * @since 1.2
 592      */
 593     public void disconnect() {
 594         synchronized (this) {
 595             if (isClosed())
 596                 return;
 597             if (connectState == ST_CONNECTED) {
 598                 impl.disconnect ();
 599             }
 600             connectedAddress = null;
 601             connectedPort = -1;
 602             connectState = ST_NOT_CONNECTED;
 603             explicitFilter = false;
 604         }
 605     }
 606 
 607     /**
 608      * Returns the binding state of the socket.
 609      * <p>
 610      * If the socket was bound prior to being {@link #close closed},
 611      * then this method will continue to return {@code true}
 612      * after the socket is closed.
 613      *
 614      * @return true if the socket successfully bound to an address
 615      * @since 1.4
 616      */
 617     public boolean isBound() {
 618         return bound;
 619     }
 620 
 621     /**
 622      * Returns the connection state of the socket.
 623      * <p>
 624      * If the socket was connected prior to being {@link #close closed},
 625      * then this method will continue to return {@code true}
 626      * after the socket is closed.
 627      *
 628      * @return true if the socket successfully connected to a server
 629      * @since 1.4
 630      */
 631     public boolean isConnected() {
 632         return connectState != ST_NOT_CONNECTED;
 633     }
 634 
 635     /**
 636      * Returns the address to which this socket is connected. Returns
 637      * {@code null} if the socket is not connected.
 638      * <p>
 639      * If the socket was connected prior to being {@link #close closed},
 640      * then this method will continue to return the connected address
 641      * after the socket is closed.
 642      *
 643      * @return the address to which this socket is connected.
 644      * @since 1.2
 645      */
 646     public InetAddress getInetAddress() {
 647         return connectedAddress;
 648     }
 649 
 650     /**
 651      * Returns the port number to which this socket is connected.
 652      * Returns {@code -1} if the socket is not connected.
 653      * <p>
 654      * If the socket was connected prior to being {@link #close closed},
 655      * then this method will continue to return the connected port number
 656      * after the socket is closed.
 657      *
 658      * @return the port number to which this socket is connected.
 659      * @since 1.2
 660      */
 661     public int getPort() {
 662         return connectedPort;
 663     }
 664 
 665     /**
 666      * Returns the address of the endpoint this socket is connected to, or
 667      * {@code null} if it is unconnected.
 668      * <p>
 669      * If the socket was connected prior to being {@link #close closed},
 670      * then this method will continue to return the connected address
 671      * after the socket is closed.
 672      *
 673      * @return a {@code SocketAddress} representing the remote
 674      *         endpoint of this socket, or {@code null} if it is
 675      *         not connected yet.
 676      * @see #getInetAddress()
 677      * @see #getPort()
 678      * @see #connect(SocketAddress)
 679      * @since 1.4
 680      */
 681     public SocketAddress getRemoteSocketAddress() {
 682         if (!isConnected())
 683             return null;
 684         return new InetSocketAddress(getInetAddress(), getPort());
 685     }
 686 
 687     /**
 688      * Returns the address of the endpoint this socket is bound to.
 689      *
 690      * @return a {@code SocketAddress} representing the local endpoint of this
 691      *         socket, or {@code null} if it is closed or not bound yet.
 692      * @see #getLocalAddress()
 693      * @see #getLocalPort()
 694      * @see #bind(SocketAddress)
 695      * @since 1.4
 696      */
 697     public SocketAddress getLocalSocketAddress() {
 698         if (isClosed())
 699             return null;
 700         if (!isBound())
 701             return null;
 702         return new InetSocketAddress(getLocalAddress(), getLocalPort());
 703     }
 704 
 705     /**
 706      * Sends a datagram packet from this socket. The
 707      * {@code DatagramPacket} includes information indicating the
 708      * data to be sent, its length, the IP address of the remote host,
 709      * and the port number on the remote host.
 710      *
 711      * <p>If there is a security manager, and the socket is not currently
 712      * connected to a remote address, this method first performs some
 713      * security checks. First, if {@code p.getAddress().isMulticastAddress()}
 714      * is true, this method calls the
 715      * security manager's {@code checkMulticast} method
 716      * with {@code p.getAddress()} as its argument.
 717      * If the evaluation of that expression is false,
 718      * this method instead calls the security manager's
 719      * {@code checkConnect} method with arguments
 720      * {@code p.getAddress().getHostAddress()} and
 721      * {@code p.getPort()}. Each call to a security manager method
 722      * could result in a SecurityException if the operation is not allowed.
 723      *
 724      * @param      p   the {@code DatagramPacket} to be sent.
 725      *
 726      * @throws     IOException  if an I/O error occurs.
 727      * @throws     SecurityException  if a security manager exists and its
 728      *             {@code checkMulticast} or {@code checkConnect}
 729      *             method doesn't allow the send.
 730      * @throws     PortUnreachableException may be thrown if the socket is connected
 731      *             to a currently unreachable destination. Note, there is no
 732      *             guarantee that the exception will be thrown.
 733      * @throws     java.nio.channels.IllegalBlockingModeException
 734      *             if this socket has an associated channel,
 735      *             and the channel is in non-blocking mode.
 736      * @throws     IllegalArgumentException if the socket is connected,
 737      *             and connected address and packet address differ, or
 738      *             if the socket is not connected and the packet address
 739      *             is not set or if its port is out of range.
 740      *
 741      * @see        java.net.DatagramPacket
 742      * @see        SecurityManager#checkMulticast(InetAddress)
 743      * @see        SecurityManager#checkConnect
 744      * @revised 1.4
 745      * @spec JSR-51
 746      */
 747     public void send(DatagramPacket p) throws IOException  {
 748         synchronized (p) {
 749             if (isClosed())
 750                 throw new SocketException("Socket is closed");
 751             InetAddress packetAddress = p.getAddress();
 752             int packetPort = p.getPort();
 753             checkAddress (packetAddress, "send");
 754             if (connectState == ST_NOT_CONNECTED) {
 755                 if (packetAddress == null) {
 756                     throw new IllegalArgumentException("Address not set");
 757                 }
 758                 if (packetPort < 0 || packetPort > 0xFFFF)
 759                     throw new IllegalArgumentException("port out of range:" + packetPort);
 760                 // check the address is ok with the security manager on every send.
 761                 SecurityManager security = System.getSecurityManager();
 762 
 763                 // The reason you want to synchronize on datagram packet
 764                 // is because you don't want an applet to change the address
 765                 // while you are trying to send the packet for example
 766                 // after the security check but before the send.
 767                 if (security != null) {
 768                     if (packetAddress.isMulticastAddress()) {
 769                         security.checkMulticast(packetAddress);
 770                     } else {
 771                         security.checkConnect(packetAddress.getHostAddress(),
 772                                 packetPort);
 773                     }
 774                 }
 775             } else {
 776                 // we're connected
 777                 if (packetAddress == null) {
 778                     p.setAddress(connectedAddress);
 779                     p.setPort(connectedPort);
 780                 } else if ((!packetAddress.equals(connectedAddress)) ||
 781                         packetPort != connectedPort) {
 782                     throw new IllegalArgumentException("connected address " +
 783                                                        "and packet address" +
 784                                                        " differ");
 785                 }
 786             }
 787             // Check whether the socket is bound
 788             if (!isBound())
 789                 bind(new InetSocketAddress(0));
 790             // call the  method to send
 791             getImpl().send(p);
 792         }
 793     }
 794 
 795     /**
 796      * Receives a datagram packet from this socket. When this method
 797      * returns, the {@code DatagramPacket}'s buffer is filled with
 798      * the data received. The datagram packet also contains the sender's
 799      * IP address, and the port number on the sender's machine.
 800      * <p>
 801      * This method blocks until a datagram is received. The
 802      * {@code length} field of the datagram packet object contains
 803      * the length of the received message. If the message is longer than
 804      * the packet's length, the message is truncated.
 805      * <p>
 806      * If there is a security manager, and the socket is not currently
 807      * connected to a remote address, a packet cannot be received if the
 808      * security manager's {@code checkAccept} method does not allow it.
 809      * Datagrams that are not permitted by the security manager are silently
 810      * discarded.
 811      *
 812      * @param      p   the {@code DatagramPacket} into which to place
 813      *                 the incoming data.
 814      * @throws     IOException  if an I/O error occurs.
 815      * @throws     SocketTimeoutException  if setSoTimeout was previously called
 816      *                 and the timeout has expired.
 817      * @throws     PortUnreachableException may be thrown if the socket is connected
 818      *             to a currently unreachable destination. Note, there is no guarantee that the
 819      *             exception will be thrown.
 820      * @throws     java.nio.channels.IllegalBlockingModeException
 821      *             if this socket has an associated channel,
 822      *             and the channel is in non-blocking mode.
 823      * @see        java.net.DatagramPacket
 824      * @see        java.net.DatagramSocket
 825      * @revised 1.4
 826      * @spec JSR-51
 827      */
 828     public synchronized void receive(DatagramPacket p) throws IOException {
 829         synchronized (p) {
 830             if (!isBound())
 831                 bind(new InetSocketAddress(0));
 832             if (connectState == ST_NOT_CONNECTED) {
 833                 // check the address is ok with the security manager before every recv.
 834                 SecurityManager security = System.getSecurityManager();
 835                 if (security != null) {
 836                     while(true) {
 837                         String peekAd = null;
 838                         int peekPort = 0;
 839                         // peek at the packet to see who it is from.
 840                         if (!oldImpl) {
 841                             // We can use the new peekData() API
 842                             DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
 843                             peekPort = getImpl().peekData(peekPacket);
 844                             peekAd = peekPacket.getAddress().getHostAddress();
 845                         } else {
 846                             InetAddress adr = new InetAddress();
 847                             peekPort = getImpl().peek(adr);
 848                             peekAd = adr.getHostAddress();
 849                         }
 850                         try {
 851                             security.checkAccept(peekAd, peekPort);
 852                             // security check succeeded - so now break
 853                             // and recv the packet.
 854                             break;
 855                         } catch (SecurityException se) {
 856                             // Throw away the offending packet by consuming
 857                             // it in a tmp buffer.
 858                             DatagramPacket tmp = new DatagramPacket(new byte[1], 1);
 859                             getImpl().receive(tmp);
 860 
 861                             // silently discard the offending packet
 862                             // and continue: unknown/malicious
 863                             // entities on nets should not make
 864                             // runtime throw security exception and
 865                             // disrupt the applet by sending random
 866                             // datagram packets.
 867                             continue;
 868                         }
 869                     } // end of while
 870                 }
 871             }
 872             DatagramPacket tmp = null;
 873             if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) {
 874                 // We have to do the filtering the old fashioned way since
 875                 // the native impl doesn't support connect or the connect
 876                 // via the impl failed, or .. "explicitFilter" may be set when
 877                 // a socket is connected via the impl, for a period of time
 878                 // when packets from other sources might be queued on socket.
 879                 boolean stop = false;
 880                 while (!stop) {
 881                     InetAddress peekAddress = null;
 882                     int peekPort = -1;
 883                     // peek at the packet to see who it is from.
 884                     if (!oldImpl) {
 885                         // We can use the new peekData() API
 886                         DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
 887                         peekPort = getImpl().peekData(peekPacket);
 888                         peekAddress = peekPacket.getAddress();
 889                     } else {
 890                         // this api only works for IPv4
 891                         peekAddress = new InetAddress();
 892                         peekPort = getImpl().peek(peekAddress);
 893                     }
 894                     if ((!connectedAddress.equals(peekAddress)) ||
 895                         (connectedPort != peekPort)) {
 896                         // throw the packet away and silently continue
 897                         tmp = new DatagramPacket(
 898                                                 new byte[1024], 1024);
 899                         getImpl().receive(tmp);
 900                         if (explicitFilter) {
 901                             if (checkFiltering(tmp)) {
 902                                 stop = true;
 903                             }
 904                         }
 905                     } else {
 906                         stop = true;
 907                     }
 908                 }
 909             }
 910             // If the security check succeeds, or the datagram is
 911             // connected then receive the packet
 912             getImpl().receive(p);
 913             if (explicitFilter && tmp == null) {
 914                 // packet was not filtered, account for it here
 915                 checkFiltering(p);
 916             }
 917         }
 918     }
 919 
 920     private boolean checkFiltering(DatagramPacket p) throws SocketException {
 921         bytesLeftToFilter -= p.getLength();
 922         if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) {
 923             explicitFilter = false;
 924             return true;
 925         }
 926         return false;
 927     }
 928 
 929     /**
 930      * Gets the local address to which the socket is bound.
 931      *
 932      * <p>If there is a security manager, its
 933      * {@code checkConnect} method is first called
 934      * with the host address and {@code -1}
 935      * as its arguments to see if the operation is allowed.
 936      *
 937      * @see SecurityManager#checkConnect
 938      * @return  the local address to which the socket is bound,
 939      *          {@code null} if the socket is closed, or
 940      *          an {@code InetAddress} representing
 941      *          {@link InetAddress#isAnyLocalAddress wildcard}
 942      *          address if either the socket is not bound, or
 943      *          the security manager {@code checkConnect}
 944      *          method does not allow the operation
 945      * @since   1.1
 946      */
 947     public InetAddress getLocalAddress() {
 948         if (isClosed())
 949             return null;
 950         InetAddress in;
 951         try {
 952             in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
 953             if (in.isAnyLocalAddress()) {
 954                 in = InetAddress.anyLocalAddress();
 955             }
 956             SecurityManager s = System.getSecurityManager();
 957             if (s != null) {
 958                 s.checkConnect(in.getHostAddress(), -1);
 959             }
 960         } catch (Exception e) {
 961             in = InetAddress.anyLocalAddress(); // "0.0.0.0"
 962         }
 963         return in;
 964     }
 965 
 966     /**
 967      * Returns the port number on the local host to which this socket
 968      * is bound.
 969      *
 970      * @return  the port number on the local host to which this socket is bound,
 971      *          {@code -1} if the socket is closed, or
 972      *          {@code 0} if it is not bound yet.
 973      */
 974     public int getLocalPort() {
 975         if (isClosed())
 976             return -1;
 977         try {
 978             return getImpl().getLocalPort();
 979         } catch (Exception e) {
 980             return 0;
 981         }
 982     }
 983 
 984     /**
 985      * Enable/disable SO_TIMEOUT with the specified timeout, in
 986      * milliseconds. With this option set to a positive timeout value,
 987      * a call to receive() for this DatagramSocket
 988      * will block for only this amount of time.  If the timeout expires,
 989      * a <B>java.net.SocketTimeoutException</B> is raised, though the
 990      * DatagramSocket is still valid. A timeout of zero is interpreted
 991      * as an infinite timeout.
 992      * The option <B>must</B> be enabled prior to entering the blocking
 993      * operation to have effect.
 994      *
 995      * @param timeout the specified timeout in milliseconds.
 996      * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
 997      * @throws IllegalArgumentException if {@code timeout} is negative
 998      * @since   1.1
 999      * @see #getSoTimeout()
1000      */
1001     public synchronized void setSoTimeout(int timeout) throws SocketException {
1002         if (isClosed())
1003             throw new SocketException("Socket is closed");
1004         if (timeout < 0)
1005             throw new IllegalArgumentException("timeout < 0");
1006         getImpl().setOption(SocketOptions.SO_TIMEOUT, timeout);
1007     }
1008 
1009     /**
1010      * Retrieve setting for SO_TIMEOUT.  0 returns implies that the
1011      * option is disabled (i.e., timeout of infinity).
1012      *
1013      * @return the setting for SO_TIMEOUT
1014      * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
1015      * @since   1.1
1016      * @see #setSoTimeout(int)
1017      */
1018     public synchronized int getSoTimeout() throws SocketException {
1019         if (isClosed())
1020             throw new SocketException("Socket is closed");
1021         if (getImpl() == null)
1022             return 0;
1023         Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
1024         /* extra type safety */
1025         if (o instanceof Integer) {
1026             return ((Integer) o).intValue();
1027         } else {
1028             return 0;
1029         }
1030     }
1031 
1032     /**
1033      * Sets the SO_SNDBUF option to the specified value for this
1034      * {@code DatagramSocket}. The SO_SNDBUF option is used by the
1035      * network implementation as a hint to size the underlying
1036      * network I/O buffers. The SO_SNDBUF setting may also be used
1037      * by the network implementation to determine the maximum size
1038      * of the packet that can be sent on this socket.
1039      * <p>
1040      * As SO_SNDBUF is a hint, applications that want to verify
1041      * what size the buffer is should call {@link #getSendBufferSize()}.
1042      * <p>
1043      * Increasing the buffer size may allow multiple outgoing packets
1044      * to be queued by the network implementation when the send rate
1045      * is high.
1046      * <p>
1047      * Note: If {@link #send(DatagramPacket)} is used to send a
1048      * {@code DatagramPacket} that is larger than the setting
1049      * of SO_SNDBUF then it is implementation specific if the
1050      * packet is sent or discarded.
1051      *
1052      * @param size the size to which to set the send buffer
1053      * size. This value must be greater than 0.
1054      *
1055      * @throws    SocketException if there is an error
1056      * in the underlying protocol, such as an UDP error.
1057      * @throws    IllegalArgumentException if the value is 0 or is
1058      * negative.
1059      * @see #getSendBufferSize()
1060      * @since 1.2
1061      */
1062     public synchronized void setSendBufferSize(int size) throws SocketException {
1063         if (!(size > 0)) {
1064             throw new IllegalArgumentException("negative send size");
1065         }
1066         if (isClosed())
1067             throw new SocketException("Socket is closed");
1068         getImpl().setOption(SocketOptions.SO_SNDBUF, size);
1069     }
1070 
1071     /**
1072      * Get value of the SO_SNDBUF option for this {@code DatagramSocket}, that is the
1073      * buffer size used by the platform for output on this {@code DatagramSocket}.
1074      *
1075      * @return the value of the SO_SNDBUF option for this {@code DatagramSocket}
1076      * @throws    SocketException if there is an error in
1077      * the underlying protocol, such as an UDP error.
1078      * @see #setSendBufferSize
1079      * @since 1.2
1080      */
1081     public synchronized int getSendBufferSize() throws SocketException {
1082         if (isClosed())
1083             throw new SocketException("Socket is closed");
1084         int result = 0;
1085         Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
1086         if (o instanceof Integer) {
1087             result = ((Integer)o).intValue();
1088         }
1089         return result;
1090     }
1091 
1092     /**
1093      * Sets the SO_RCVBUF option to the specified value for this
1094      * {@code DatagramSocket}. The SO_RCVBUF option is used by
1095      * the network implementation as a hint to size the underlying
1096      * network I/O buffers. The SO_RCVBUF setting may also be used
1097      * by the network implementation to determine the maximum size
1098      * of the packet that can be received on this socket.
1099      * <p>
1100      * Because SO_RCVBUF is a hint, applications that want to
1101      * verify what size the buffers were set to should call
1102      * {@link #getReceiveBufferSize()}.
1103      * <p>
1104      * Increasing SO_RCVBUF may allow the network implementation
1105      * to buffer multiple packets when packets arrive faster than
1106      * are being received using {@link #receive(DatagramPacket)}.
1107      * <p>
1108      * Note: It is implementation specific if a packet larger
1109      * than SO_RCVBUF can be received.
1110      *
1111      * @param size the size to which to set the receive buffer
1112      * size. This value must be greater than 0.
1113      *
1114      * @throws    SocketException if there is an error in
1115      * the underlying protocol, such as an UDP error.
1116      * @throws    IllegalArgumentException if the value is 0 or is
1117      * negative.
1118      * @see #getReceiveBufferSize()
1119      * @since 1.2
1120      */
1121     public synchronized void setReceiveBufferSize(int size) throws SocketException {
1122         if (size <= 0) {
1123             throw new IllegalArgumentException("invalid receive size");
1124         }
1125         if (isClosed())
1126             throw new SocketException("Socket is closed");
1127         getImpl().setOption(SocketOptions.SO_RCVBUF, size);
1128     }
1129 
1130     /**
1131      * Get value of the SO_RCVBUF option for this {@code DatagramSocket}, that is the
1132      * buffer size used by the platform for input on this {@code DatagramSocket}.
1133      *
1134      * @return the value of the SO_RCVBUF option for this {@code DatagramSocket}
1135      * @throws    SocketException if there is an error in the underlying protocol, such as an UDP error.
1136      * @see #setReceiveBufferSize(int)
1137      * @since 1.2
1138      */
1139     public synchronized int getReceiveBufferSize() throws SocketException {
1140         if (isClosed())
1141             throw new SocketException("Socket is closed");
1142         int result = 0;
1143         Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
1144         if (o instanceof Integer) {
1145             result = ((Integer)o).intValue();
1146         }
1147         return result;
1148     }
1149 
1150     /**
1151      * Enable/disable the SO_REUSEADDR socket option.
1152      * <p>
1153      * For UDP sockets it may be necessary to bind more than one
1154      * socket to the same socket address. This is typically for the
1155      * purpose of receiving multicast packets
1156      * (See {@link java.net.MulticastSocket}). The
1157      * {@code SO_REUSEADDR} socket option allows multiple
1158      * sockets to be bound to the same socket address if the
1159      * {@code SO_REUSEADDR} socket option is enabled prior
1160      * to binding the socket using {@link #bind(SocketAddress)}.
1161      * <p>
1162      * Note: This functionality is not supported by all existing platforms,
1163      * so it is implementation specific whether this option will be ignored
1164      * or not. However, if it is not supported then
1165      * {@link #getReuseAddress()} will always return {@code false}.
1166      * <p>
1167      * When a {@code DatagramSocket} is created the initial setting
1168      * of {@code SO_REUSEADDR} is disabled.
1169      * <p>
1170      * The behaviour when {@code SO_REUSEADDR} is enabled or
1171      * disabled after a socket is bound (See {@link #isBound()})
1172      * is not defined.
1173      *
1174      * @param on  whether to enable or disable the
1175      * @throws    SocketException if an error occurs enabling or
1176      *            disabling the {@code SO_REUSEADDR} socket option,
1177      *            or the socket is closed.
1178      * @since 1.4
1179      * @see #getReuseAddress()
1180      * @see #bind(SocketAddress)
1181      * @see #isBound()
1182      * @see #isClosed()
1183      */
1184     public synchronized void setReuseAddress(boolean on) throws SocketException {
1185         if (isClosed())
1186             throw new SocketException("Socket is closed");
1187         // Integer instead of Boolean for compatibility with older DatagramSocketImpl
1188         if (oldImpl)
1189             getImpl().setOption(SocketOptions.SO_REUSEADDR, on?-1:0);
1190         else
1191             getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
1192     }
1193 
1194     /**
1195      * Tests if SO_REUSEADDR is enabled.
1196      *
1197      * @return a {@code boolean} indicating whether or not SO_REUSEADDR is enabled.
1198      * @throws    SocketException if there is an error
1199      * in the underlying protocol, such as an UDP error.
1200      * @since   1.4
1201      * @see #setReuseAddress(boolean)
1202      */
1203     public synchronized boolean getReuseAddress() throws SocketException {
1204         if (isClosed())
1205             throw new SocketException("Socket is closed");
1206         Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR);
1207         return ((Boolean)o).booleanValue();
1208     }
1209 
1210     /**
1211      * Enable/disable SO_BROADCAST.
1212      *
1213      * <p> Some operating systems may require that the Java virtual machine be
1214      * started with implementation specific privileges to enable this option or
1215      * send broadcast datagrams.
1216      *
1217      * @param  on
1218      *         whether or not to have broadcast turned on.
1219      *
1220      * @throws  SocketException
1221      *          if there is an error in the underlying protocol, such as an UDP
1222      *          error.
1223      *
1224      * @since 1.4
1225      * @see #getBroadcast()
1226      */
1227     public synchronized void setBroadcast(boolean on) throws SocketException {
1228         if (isClosed())
1229             throw new SocketException("Socket is closed");
1230         getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(on));
1231     }
1232 
1233     /**
1234      * Tests if SO_BROADCAST is enabled.
1235      * @return a {@code boolean} indicating whether or not SO_BROADCAST is enabled.
1236      * @throws    SocketException if there is an error
1237      * in the underlying protocol, such as an UDP error.
1238      * @since 1.4
1239      * @see #setBroadcast(boolean)
1240      */
1241     public synchronized boolean getBroadcast() throws SocketException {
1242         if (isClosed())
1243             throw new SocketException("Socket is closed");
1244         return ((Boolean)(getImpl().getOption(SocketOptions.SO_BROADCAST))).booleanValue();
1245     }
1246 
1247     /**
1248      * Sets traffic class or type-of-service octet in the IP
1249      * datagram header for datagrams sent from this DatagramSocket.
1250      * As the underlying network implementation may ignore this
1251      * value applications should consider it a hint.
1252      *
1253      * <P> The tc <B>must</B> be in the range {@code 0 <= tc <=
1254      * 255} or an IllegalArgumentException will be thrown.
1255      * <p>Notes:
1256      * <p>For Internet Protocol v4 the value consists of an
1257      * {@code integer}, the least significant 8 bits of which
1258      * represent the value of the TOS octet in IP packets sent by
1259      * the socket.
1260      * RFC 1349 defines the TOS values as follows:
1261      *
1262      * <UL>
1263      * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
1264      * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
1265      * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
1266      * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
1267      * </UL>
1268      * The last low order bit is always ignored as this
1269      * corresponds to the MBZ (must be zero) bit.
1270      * <p>
1271      * Setting bits in the precedence field may result in a
1272      * SocketException indicating that the operation is not
1273      * permitted.
1274      * <p>
1275      * for Internet Protocol v6 {@code tc} is the value that
1276      * would be placed into the sin6_flowinfo field of the IP header.
1277      *
1278      * @param tc        an {@code int} value for the bitset.
1279      * @throws SocketException if there is an error setting the
1280      * traffic class or type-of-service
1281      * @since 1.4
1282      * @see #getTrafficClass
1283      */
1284     public synchronized void setTrafficClass(int tc) throws SocketException {
1285         if (tc < 0 || tc > 255)
1286             throw new IllegalArgumentException("tc is not in range 0 -- 255");
1287 
1288         if (isClosed())
1289             throw new SocketException("Socket is closed");
1290         try {
1291             getImpl().setOption(SocketOptions.IP_TOS, tc);
1292         } catch (SocketException se) {
1293             // not supported if socket already connected
1294             // Solaris returns error in such cases
1295             if(!isConnected())
1296                 throw se;
1297         }
1298     }
1299 
1300     /**
1301      * Gets traffic class or type-of-service in the IP datagram
1302      * header for packets sent from this DatagramSocket.
1303      * <p>
1304      * As the underlying network implementation may ignore the
1305      * traffic class or type-of-service set using {@link #setTrafficClass(int)}
1306      * this method may return a different value than was previously
1307      * set using the {@link #setTrafficClass(int)} method on this
1308      * DatagramSocket.
1309      *
1310      * @return the traffic class or type-of-service already set
1311      * @throws SocketException if there is an error obtaining the
1312      * traffic class or type-of-service value.
1313      * @since 1.4
1314      * @see #setTrafficClass(int)
1315      */
1316     public synchronized int getTrafficClass() throws SocketException {
1317         if (isClosed())
1318             throw new SocketException("Socket is closed");
1319         return ((Integer)(getImpl().getOption(SocketOptions.IP_TOS))).intValue();
1320     }
1321 
1322     /**
1323      * Closes this datagram socket.
1324      * <p>
1325      * Any thread currently blocked in {@link #receive} upon this socket
1326      * will throw a {@link SocketException}.
1327      *
1328      * <p> If this socket has an associated channel then the channel is closed
1329      * as well.
1330      *
1331      * @revised 1.4
1332      * @spec JSR-51
1333      */
1334     public void close() {
1335         synchronized(closeLock) {
1336             if (isClosed())
1337                 return;
1338             impl.close();
1339             closed = true;
1340         }
1341     }
1342 
1343     /**
1344      * Returns whether the socket is closed or not.
1345      *
1346      * @return true if the socket has been closed
1347      * @since 1.4
1348      */
1349     public boolean isClosed() {
1350         synchronized(closeLock) {
1351             return closed;
1352         }
1353     }
1354 
1355     /**
1356      * Returns the unique {@link java.nio.channels.DatagramChannel} object
1357      * associated with this datagram socket, if any.
1358      *
1359      * <p> A datagram socket will have a channel if, and only if, the channel
1360      * itself was created via the {@link java.nio.channels.DatagramChannel#open
1361      * DatagramChannel.open} method.
1362      *
1363      * @return  the datagram channel associated with this datagram socket,
1364      *          or {@code null} if this socket was not created for a channel
1365      *
1366      * @since 1.4
1367      * @spec JSR-51
1368      */
1369     public DatagramChannel getChannel() {
1370         return null;
1371     }
1372 
1373     /**
1374      * User defined factory for all datagram sockets.
1375      */
1376     private static volatile DatagramSocketImplFactory factory;
1377 
1378     /**
1379      * Sets the datagram socket implementation factory for the
1380      * application. The factory can be specified only once.
1381      * <p>
1382      * When an application creates a new datagram socket, the socket
1383      * implementation factory's {@code createDatagramSocketImpl} method is
1384      * called to create the actual datagram socket implementation.
1385      * <p>
1386      * Passing {@code null} to the method is a no-op unless the factory
1387      * was already set.
1388      *
1389      * <p>If there is a security manager, this method first calls
1390      * the security manager's {@code checkSetFactory} method
1391      * to ensure the operation is allowed.
1392      * This could result in a SecurityException.
1393      *
1394      * @param      fac   the desired factory.
1395      * @throws     IOException  if an I/O error occurs when setting the
1396      *              datagram socket factory.
1397      * @throws     SocketException  if the factory is already defined.
1398      * @throws     SecurityException  if a security manager exists and its
1399      *             {@code checkSetFactory} method doesn't allow the operation.
1400      * @see       java.net.DatagramSocketImplFactory#createDatagramSocketImpl()
1401      * @see       SecurityManager#checkSetFactory
1402      * @since 1.3
1403      */
1404     public static synchronized void
1405     setDatagramSocketImplFactory(DatagramSocketImplFactory fac)
1406        throws IOException
1407     {
1408         if (factory != null) {
1409             throw new SocketException("factory already defined");
1410         }
1411         SecurityManager security = System.getSecurityManager();
1412         if (security != null) {
1413             security.checkSetFactory();
1414         }
1415         factory = fac;
1416     }
1417 
1418     /**
1419      * Sets the value of a socket option.
1420      *
1421      * @param <T> The type of the socket option value
1422      * @param name The socket option
1423      * @param value The value of the socket option. A value of {@code null}
1424      *              may be valid for some options.
1425      *
1426      * @return this DatagramSocket
1427      *
1428      * @throws UnsupportedOperationException if the datagram socket
1429      *         does not support the option.
1430      *
1431      * @throws IllegalArgumentException if the value is not valid for
1432      *         the option.
1433      *
1434      * @throws IOException if an I/O error occurs, or if the socket is closed.
1435      *
1436      * @throws SecurityException if a security manager is set and if the socket
1437      *         option requires a security permission and if the caller does
1438      *         not have the required permission.
1439      *         {@link java.net.StandardSocketOptions StandardSocketOptions}
1440      *         do not require any security permission.
1441      *
1442      * @throws NullPointerException if name is {@code null}
1443      *
1444      * @since 9
1445      */
1446     public <T> DatagramSocket setOption(SocketOption<T> name, T value)
1447         throws IOException
1448     {
1449         Objects.requireNonNull(name);
1450         if (isClosed())
1451             throw new SocketException("Socket is closed");
1452         getImpl().setOption(name, value);
1453         return this;
1454     }
1455 
1456     /**
1457      * Returns the value of a socket option.
1458      *
1459      * @param <T> The type of the socket option value
1460      * @param name The socket option
1461      *
1462      * @return The value of the socket option.
1463      *
1464      * @throws UnsupportedOperationException if the datagram socket
1465      *         does not support the option.
1466      *
1467      * @throws IOException if an I/O error occurs, or if the socket is closed.
1468      *
1469      * @throws NullPointerException if name is {@code null}
1470      *
1471      * @throws SecurityException if a security manager is set and if the socket
1472      *         option requires a security permission and if the caller does
1473      *         not have the required permission.
1474      *         {@link java.net.StandardSocketOptions StandardSocketOptions}
1475      *         do not require any security permission.
1476      *
1477      * @since 9
1478      */
1479     public <T> T getOption(SocketOption<T> name) throws IOException {
1480         Objects.requireNonNull(name);
1481         if (isClosed())
1482             throw new SocketException("Socket is closed");
1483         return getImpl().getOption(name);
1484     }
1485 
1486     /*package*/ volatile Set<SocketOption<?>> options;
1487     private final Object optionsLock = new Object();
1488 
1489     /**
1490      * Returns a set of the socket options supported by this socket.
1491      *
1492      * This method will continue to return the set of options even after
1493      * the socket has been closed.
1494      *
1495      * @return A set of the socket options supported by this socket. This set
1496      *        may be empty if the socket's DatagramSocketImpl cannot be created.
1497      *
1498      * @since 9
1499      */
1500     public Set<SocketOption<?>> supportedOptions() {
1501         Set<SocketOption<?>> options = this.options;
1502         if (options != null)
1503             return options;
1504 
1505         synchronized (optionsLock) {
1506             options = this.options;
1507             if (options != null)
1508                 return options;
1509 
1510             try {
1511                 DatagramSocketImpl impl = getImpl();
1512                 options = Collections.unmodifiableSet(impl.supportedOptions());
1513             } catch (IOException e) {
1514                 options = Collections.emptySet();
1515             }
1516             return this.options = options;
1517         }
1518     }
1519 }