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