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 private static Set<SocketOption<?>> options; 1487 private static boolean optionsSet = false; 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 synchronized(DatagramSocket.class) { 1502 if (optionsSet) { 1503 return options; 1504 } 1505 try { 1506 DatagramSocketImpl impl = getImpl(); 1507 options = Collections.unmodifiableSet(impl.supportedOptions()); 1508 } catch (IOException e) { 1509 options = Collections.emptySet(); 1510 } 1511 optionsSet = true; 1512 return options; 1513 } 1514 } 1515 }