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