GNU Classpath (0.95) | |
Frames | No Frames |
1: /* DatagramSocket.java -- A class to model UDP sockets 2: Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006 3: Free Software Foundation, Inc. 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: package java.net; 40: 41: import gnu.classpath.SystemProperties; 42: 43: import gnu.java.net.PlainDatagramSocketImpl; 44: import gnu.java.nio.DatagramChannelImpl; 45: 46: import java.io.IOException; 47: import java.nio.channels.DatagramChannel; 48: import java.nio.channels.IllegalBlockingModeException; 49: 50: 51: /** 52: * Written using on-line Java Platform 1.2 API Specification, as well 53: * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). 54: * Status: Believed complete and correct. 55: */ 56: /** 57: * This class models a connectionless datagram socket that sends 58: * individual packets of data across the network. In the TCP/IP world, 59: * this means UDP. Datagram packets do not have guaranteed delivery, 60: * or any guarantee about the order the data will be received on the 61: * remote host. 62: * 63: * @author Aaron M. Renn (arenn@urbanophile.com) 64: * @author Warren Levy (warrenl@cygnus.com) 65: * @date May 3, 1999. 66: */ 67: public class DatagramSocket 68: { 69: /** 70: * This is the user DatagramSocketImplFactory for this class. If this 71: * variable is null, a default factory is used. 72: */ 73: private static DatagramSocketImplFactory factory; 74: 75: /** 76: * This is the implementation object used by this socket. 77: */ 78: private DatagramSocketImpl impl; 79: 80: /** 81: * True if socket implementation was created. 82: */ 83: private boolean implCreated; 84: 85: /** 86: * This is the address we are "connected" to 87: */ 88: private InetAddress remoteAddress; 89: 90: /** 91: * This is the port we are "connected" to 92: */ 93: private int remotePort = -1; 94: 95: /** 96: * True if socket is bound. 97: */ 98: private boolean bound; 99: 100: /** 101: * Creates a <code>DatagramSocket</code> from a specified 102: * <code>DatagramSocketImpl</code> instance 103: * 104: * @param impl The <code>DatagramSocketImpl</code> the socket will be 105: * created from 106: * 107: * @since 1.4 108: */ 109: protected DatagramSocket(DatagramSocketImpl impl) 110: { 111: if (impl == null) 112: throw new NullPointerException("impl may not be null"); 113: 114: this.impl = impl; 115: this.remoteAddress = null; 116: this.remotePort = -1; 117: } 118: 119: /** 120: * Initializes a new instance of <code>DatagramSocket</code> that binds to 121: * a random port and every address on the local machine. 122: * 123: * @exception SocketException If an error occurs. 124: * @exception SecurityException If a security manager exists and 125: * its <code>checkListen</code> method doesn't allow the operation. 126: */ 127: public DatagramSocket() throws SocketException 128: { 129: this(new InetSocketAddress(0)); 130: } 131: 132: /** 133: * Initializes a new instance of <code>DatagramSocket</code> that binds to 134: * the specified port and every address on the local machine. 135: * 136: * @param port The local port number to bind to. 137: * 138: * @exception SecurityException If a security manager exists and its 139: * <code>checkListen</code> method doesn't allow the operation. 140: * @exception SocketException If an error occurs. 141: */ 142: public DatagramSocket(int port) throws SocketException 143: { 144: this(new InetSocketAddress(port)); 145: } 146: 147: /** 148: * Initializes a new instance of <code>DatagramSocket</code> that binds to 149: * the specified local port and address. 150: * 151: * @param port The local port number to bind to. 152: * @param addr The local address to bind to. 153: * 154: * @exception SecurityException If a security manager exists and its 155: * checkListen method doesn't allow the operation. 156: * @exception SocketException If an error occurs. 157: */ 158: public DatagramSocket(int port, InetAddress addr) throws SocketException 159: { 160: this(new InetSocketAddress(addr, port)); 161: } 162: 163: /** 164: * Initializes a new instance of <code>DatagramSocket</code> that binds to 165: * the specified local port and address. 166: * 167: * @param address The local address and port number to bind to. 168: * 169: * @exception SecurityException If a security manager exists and its 170: * <code>checkListen</code> method doesn't allow the operation. 171: * @exception SocketException If an error occurs. 172: * 173: * @since 1.4 174: */ 175: public DatagramSocket(SocketAddress address) throws SocketException 176: { 177: String propVal = SystemProperties.getProperty("impl.prefix"); 178: if (propVal == null || propVal.equals("")) 179: { 180: if (factory != null) 181: impl = factory.createDatagramSocketImpl(); 182: else 183: { 184: try 185: { 186: impl = new PlainDatagramSocketImpl(); 187: } 188: catch (IOException ioe) 189: { 190: SocketException se = new SocketException(); 191: se.initCause(ioe); 192: throw se; 193: } 194: } 195: } 196: else 197: try 198: { 199: impl = 200: (DatagramSocketImpl) Class.forName("java.net." + propVal 201: + "DatagramSocketImpl") 202: .newInstance(); 203: } 204: catch (Exception e) 205: { 206: System.err.println("Could not instantiate class: java.net." 207: + propVal + "DatagramSocketImpl"); 208: try 209: { 210: impl = new PlainDatagramSocketImpl(); 211: } 212: catch (IOException ioe) 213: { 214: SocketException se = new SocketException(); 215: se.initCause(ioe); 216: throw se; 217: } 218: } 219: 220: if (address != null) 221: bind(address); 222: } 223: 224: // This needs to be accessible from java.net.MulticastSocket 225: DatagramSocketImpl getImpl() throws SocketException 226: { 227: try 228: { 229: if (! implCreated) 230: { 231: impl.create(); 232: implCreated = true; 233: } 234: 235: return impl; 236: } 237: catch (IOException e) 238: { 239: SocketException se = new SocketException(); 240: se.initCause(e); 241: throw se; 242: } 243: } 244: 245: /** 246: * Closes this datagram socket. 247: */ 248: public void close() 249: { 250: if (isClosed()) 251: return; 252: 253: try 254: { 255: getImpl().close(); 256: } 257: catch (SocketException e) 258: { 259: // Ignore this case, just close the socket in finally clause. 260: } 261: finally 262: { 263: remoteAddress = null; 264: remotePort = -1; 265: impl = null; 266: } 267: 268: try 269: { 270: if (getChannel() != null) 271: getChannel().close(); 272: } 273: catch (IOException e) 274: { 275: // Do nothing. 276: } 277: } 278: 279: /** 280: * This method returns the remote address to which this socket is 281: * connected. If this socket is not connected, then this method will 282: * return <code>null</code>. 283: * 284: * @return The remote address. 285: * 286: * @since 1.2 287: */ 288: public InetAddress getInetAddress() 289: { 290: return remoteAddress; 291: } 292: 293: /** 294: * This method returns the remote port to which this socket is 295: * connected. If this socket is not connected, then this method will 296: * return -1. 297: * 298: * @return The remote port. 299: * 300: * @since 1.2 301: */ 302: public int getPort() 303: { 304: return remotePort; 305: } 306: 307: /** 308: * Returns the local address this datagram socket is bound to. 309: * 310: * @return The local address is the socket is bound or null 311: * 312: * @since 1.1 313: */ 314: public InetAddress getLocalAddress() 315: { 316: if (! isBound()) 317: return null; 318: 319: InetAddress localAddr; 320: 321: try 322: { 323: localAddr = 324: (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR); 325: 326: SecurityManager s = System.getSecurityManager(); 327: if (s != null) 328: s.checkConnect(localAddr.getHostAddress(), -1); 329: } 330: catch (SecurityException e) 331: { 332: localAddr = InetAddress.ANY_IF; 333: } 334: catch (SocketException e) 335: { 336: // This cannot happen as we are bound. 337: return null; 338: } 339: 340: return localAddr; 341: } 342: 343: /** 344: * Returns the local port this socket is bound to. 345: * 346: * @return The local port number. 347: */ 348: public int getLocalPort() 349: { 350: if (isClosed()) 351: return -1; 352: 353: try 354: { 355: return getImpl().getLocalPort(); 356: } 357: catch (SocketException e) 358: { 359: // This cannot happen as we are bound. 360: return 0; 361: } 362: } 363: 364: /** 365: * Returns the value of the socket's SO_TIMEOUT setting. If this method 366: * returns 0 then SO_TIMEOUT is disabled. 367: * 368: * @return The current timeout in milliseconds. 369: * 370: * @exception SocketException If an error occurs. 371: * 372: * @since 1.1 373: */ 374: public synchronized int getSoTimeout() throws SocketException 375: { 376: if (isClosed()) 377: throw new SocketException("socket is closed"); 378: 379: Object buf = getImpl().getOption(SocketOptions.SO_TIMEOUT); 380: 381: if (buf instanceof Integer) 382: return ((Integer) buf).intValue(); 383: 384: throw new SocketException("unexpected type"); 385: } 386: 387: /** 388: * Sets the value of the socket's SO_TIMEOUT value. A value of 0 will 389: * disable SO_TIMEOUT. Any other value is the number of milliseconds 390: * a socket read/write will block before timing out. 391: * 392: * @param timeout The new SO_TIMEOUT value in milliseconds. 393: * 394: * @exception SocketException If an error occurs. 395: * 396: * @since 1.1 397: */ 398: public synchronized void setSoTimeout(int timeout) throws SocketException 399: { 400: if (isClosed()) 401: throw new SocketException("socket is closed"); 402: 403: if (timeout < 0) 404: throw new IllegalArgumentException("Invalid timeout: " + timeout); 405: 406: getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout)); 407: } 408: 409: /** 410: * This method returns the value of the system level socket option 411: * SO_SNDBUF, which is used by the operating system to tune buffer 412: * sizes for data transfers. 413: * 414: * @return The send buffer size. 415: * 416: * @exception SocketException If an error occurs. 417: * 418: * @since 1.2 419: */ 420: public int getSendBufferSize() throws SocketException 421: { 422: if (isClosed()) 423: throw new SocketException("socket is closed"); 424: 425: Object buf = getImpl().getOption(SocketOptions.SO_SNDBUF); 426: 427: if (buf instanceof Integer) 428: return ((Integer) buf).intValue(); 429: 430: throw new SocketException("unexpected type"); 431: } 432: 433: /** 434: * This method sets the value for the system level socket option 435: * SO_SNDBUF to the specified value. Note that valid values for this 436: * option are specific to a given operating system. 437: * 438: * @param size The new send buffer size. 439: * 440: * @exception SocketException If an error occurs. 441: * @exception IllegalArgumentException If size is 0 or negative. 442: * 443: * @since 1.2 444: */ 445: public void setSendBufferSize(int size) throws SocketException 446: { 447: if (isClosed()) 448: throw new SocketException("socket is closed"); 449: 450: if (size < 0) 451: throw new IllegalArgumentException("Buffer size is less than 0"); 452: 453: getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size)); 454: } 455: 456: /** 457: * This method returns the value of the system level socket option 458: * SO_RCVBUF, which is used by the operating system to tune buffer 459: * sizes for data transfers. 460: * 461: * @return The receive buffer size. 462: * 463: * @exception SocketException If an error occurs. 464: * 465: * @since 1.2 466: */ 467: public int getReceiveBufferSize() throws SocketException 468: { 469: if (isClosed()) 470: throw new SocketException("socket is closed"); 471: 472: Object buf = getImpl().getOption(SocketOptions.SO_RCVBUF); 473: 474: if (buf instanceof Integer) 475: return ((Integer) buf).intValue(); 476: 477: throw new SocketException("unexpected type"); 478: } 479: 480: /** 481: * This method sets the value for the system level socket option 482: * SO_RCVBUF to the specified value. Note that valid values for this 483: * option are specific to a given operating system. 484: * 485: * @param size The new receive buffer size. 486: * 487: * @exception SocketException If an error occurs. 488: * @exception IllegalArgumentException If size is 0 or negative. 489: * 490: * @since 1.2 491: */ 492: public void setReceiveBufferSize(int size) throws SocketException 493: { 494: if (isClosed()) 495: throw new SocketException("socket is closed"); 496: 497: if (size < 0) 498: throw new IllegalArgumentException("Buffer size is less than 0"); 499: 500: getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size)); 501: } 502: 503: /** 504: * This method connects this socket to the specified address and port. 505: * When a datagram socket is connected, it will only send or receive 506: * packets to and from the host to which it is connected. A multicast 507: * socket that is connected may only send and not receive packets. 508: * 509: * @param address The address to connect this socket to. 510: * @param port The port to connect this socket to. 511: * 512: * @exception IllegalArgumentException If address or port are invalid. 513: * @exception SecurityException If the caller is not allowed to send 514: * datagrams to or receive from this address and port. 515: * 516: * @since 1.2 517: */ 518: public void connect(InetAddress address, int port) 519: { 520: if (address == null) 521: throw new IllegalArgumentException("Connect address may not be null"); 522: 523: if ((port < 1) || (port > 65535)) 524: throw new IllegalArgumentException("Port number is illegal: " + port); 525: 526: SecurityManager sm = System.getSecurityManager(); 527: if (sm != null) 528: sm.checkConnect(address.getHostAddress(), port); 529: 530: try 531: { 532: getImpl().connect(address, port); 533: remoteAddress = address; 534: remotePort = port; 535: } 536: catch (SocketException e) 537: { 538: // This means simply not connected or connect not implemented. 539: } 540: } 541: 542: /** 543: * This method disconnects this socket from the address/port it was 544: * connected to. If the socket was not connected in the first place, 545: * this method does nothing. 546: * 547: * @since 1.2 548: */ 549: public void disconnect() 550: { 551: if (! isConnected()) 552: return; 553: 554: try 555: { 556: getImpl().disconnect(); 557: } 558: catch (SocketException e) 559: { 560: // This cannot happen as we are connected. 561: } 562: finally 563: { 564: remoteAddress = null; 565: remotePort = -1; 566: } 567: } 568: 569: /** 570: * Reads a datagram packet from the socket. Note that this method 571: * will block until a packet is received from the network. On return, 572: * the passed in <code>DatagramPacket</code> is populated with the data 573: * received and all the other information about the packet. 574: * 575: * @param p A <code>DatagramPacket</code> for storing the data 576: * 577: * @exception IOException If an error occurs. 578: * @exception SocketTimeoutException If setSoTimeout was previously called 579: * and the timeout has expired. 580: * @exception PortUnreachableException If the socket is connected to a 581: * currently unreachable destination. Note, there is no guarantee that the 582: * exception will be thrown. 583: * @exception IllegalBlockingModeException If this socket has an associated 584: * channel, and the channel is in non-blocking mode. 585: * @exception SecurityException If a security manager exists and its 586: * checkAccept method doesn't allow the receive. 587: */ 588: public synchronized void receive(DatagramPacket p) throws IOException 589: { 590: if (isClosed()) 591: throw new SocketException("socket is closed"); 592: 593: if (remoteAddress != null && remoteAddress.isMulticastAddress()) 594: throw new IOException 595: ("Socket connected to a multicast address my not receive"); 596: 597: if (getChannel() != null && ! getChannel().isBlocking() 598: && ! ((DatagramChannelImpl) getChannel()).isInChannelOperation()) 599: throw new IllegalBlockingModeException(); 600: 601: DatagramPacket p2 = new DatagramPacket(p.getData(), p.getOffset(), p.maxlen); 602: getImpl().receive(p2); 603: p.length = p2.length; 604: if (p2.getAddress() != null) 605: p.setAddress(p2.getAddress()); 606: if (p2.getPort() != -1) 607: p.setPort(p2.getPort()); 608: 609: SecurityManager s = System.getSecurityManager(); 610: if (s != null && isConnected()) 611: s.checkAccept(p.getAddress().getHostAddress(), p.getPort()); 612: } 613: 614: /** 615: * Sends the specified packet. The host and port to which the packet 616: * are to be sent should be set inside the packet. 617: * 618: * @param p The datagram packet to send. 619: * 620: * @exception IOException If an error occurs. 621: * @exception SecurityException If a security manager exists and its 622: * checkMulticast or checkConnect method doesn't allow the send. 623: * @exception PortUnreachableException If the socket is connected to a 624: * currently unreachable destination. Note, there is no guarantee that the 625: * exception will be thrown. 626: * @exception IllegalBlockingModeException If this socket has an associated 627: * channel, and the channel is in non-blocking mode. 628: */ 629: public void send(DatagramPacket p) throws IOException 630: { 631: if (isClosed()) 632: throw new SocketException("socket is closed"); 633: 634: // JDK1.2: Don't do security checks if socket is connected; see jdk1.2 api. 635: SecurityManager s = System.getSecurityManager(); 636: if (s != null && ! isConnected()) 637: { 638: InetAddress addr = p.getAddress(); 639: if (addr.isMulticastAddress()) 640: s.checkMulticast(addr); 641: else 642: s.checkConnect(addr.getHostAddress(), p.getPort()); 643: } 644: 645: if (isConnected()) 646: { 647: if (p.getAddress() != null 648: && (remoteAddress != p.getAddress() || remotePort != p.getPort())) 649: throw new IllegalArgumentException 650: ("DatagramPacket address does not match remote address"); 651: } 652: 653: // FIXME: if this is a subclass of MulticastSocket, 654: // use getTimeToLive for TTL val. 655: if (getChannel() != null && ! getChannel().isBlocking() 656: && ! ((DatagramChannelImpl) getChannel()).isInChannelOperation()) 657: throw new IllegalBlockingModeException(); 658: 659: getImpl().send(p); 660: } 661: 662: /** 663: * Binds the socket to the given socket address. 664: * 665: * @param address The socket address to bind to. 666: * 667: * @exception SocketException If an error occurs. 668: * @exception SecurityException If a security manager exists and 669: * its checkListen method doesn't allow the operation. 670: * @exception IllegalArgumentException If address type is not supported. 671: * 672: * @since 1.4 673: */ 674: public void bind(SocketAddress address) throws SocketException 675: { 676: if (isClosed()) 677: throw new SocketException("socket is closed"); 678: 679: if (address == null) 680: address = new InetSocketAddress(InetAddress.ANY_IF, 0); 681: 682: if (! (address instanceof InetSocketAddress)) 683: throw new IllegalArgumentException("unsupported address type"); 684: 685: InetAddress addr = ((InetSocketAddress) address).getAddress(); 686: int port = ((InetSocketAddress) address).getPort(); 687: 688: if (port < 0 || port > 65535) 689: throw new IllegalArgumentException("Invalid port: " + port); 690: 691: SecurityManager s = System.getSecurityManager(); 692: if (s != null) 693: s.checkListen(port); 694: 695: if (addr == null) 696: addr = InetAddress.ANY_IF; 697: 698: try 699: { 700: getImpl().bind(port, addr); 701: bound = true; 702: } 703: catch (SocketException exception) 704: { 705: getImpl().close(); 706: throw exception; 707: } 708: catch (RuntimeException exception) 709: { 710: getImpl().close(); 711: throw exception; 712: } 713: catch (Error error) 714: { 715: getImpl().close(); 716: throw error; 717: } 718: } 719: 720: /** 721: * Checks if the datagram socket is closed. 722: * 723: * @return True if socket is closed, false otherwise. 724: * 725: * @since 1.4 726: */ 727: public boolean isClosed() 728: { 729: return impl == null; 730: } 731: 732: /** 733: * Returns the datagram channel assoziated with this datagram socket. 734: * 735: * @return The associated <code>DatagramChannel</code> object or null 736: * 737: * @since 1.4 738: */ 739: public DatagramChannel getChannel() 740: { 741: return null; 742: } 743: 744: /** 745: * Connects the datagram socket to a specified socket address. 746: * 747: * @param address The socket address to connect to. 748: * 749: * @exception SocketException If an error occurs. 750: * @exception IllegalArgumentException If address type is not supported. 751: * 752: * @since 1.4 753: */ 754: public void connect(SocketAddress address) throws SocketException 755: { 756: if (isClosed()) 757: throw new SocketException("socket is closed"); 758: 759: if (! (address instanceof InetSocketAddress)) 760: throw new IllegalArgumentException("unsupported address type"); 761: 762: InetSocketAddress tmp = (InetSocketAddress) address; 763: connect(tmp.getAddress(), tmp.getPort()); 764: } 765: 766: /** 767: * Returns the binding state of the socket. 768: * 769: * @return True if socket bound, false otherwise. 770: * 771: * @since 1.4 772: */ 773: public boolean isBound() 774: { 775: return bound; 776: } 777: 778: /** 779: * Returns the connection state of the socket. 780: * 781: * @return True if socket is connected, false otherwise. 782: * 783: * @since 1.4 784: */ 785: public boolean isConnected() 786: { 787: return remoteAddress != null; 788: } 789: 790: /** 791: * Returns the SocketAddress of the host this socket is conneted to 792: * or null if this socket is not connected. 793: * 794: * @return The socket address of the remote host if connected or null 795: * 796: * @since 1.4 797: */ 798: public SocketAddress getRemoteSocketAddress() 799: { 800: if (! isConnected()) 801: return null; 802: 803: return new InetSocketAddress(remoteAddress, remotePort); 804: } 805: 806: /** 807: * Returns the local SocketAddress this socket is bound to. 808: * 809: * @return The local SocketAddress or null if the socket is not bound. 810: * 811: * @since 1.4 812: */ 813: public SocketAddress getLocalSocketAddress() 814: { 815: if (! isBound()) 816: return null; 817: 818: return new InetSocketAddress(getLocalAddress(), getLocalPort()); 819: } 820: 821: /** 822: * Enables/Disables SO_REUSEADDR. 823: * 824: * @param on Whether or not to have SO_REUSEADDR turned on. 825: * 826: * @exception SocketException If an error occurs. 827: * 828: * @since 1.4 829: */ 830: public void setReuseAddress(boolean on) throws SocketException 831: { 832: if (isClosed()) 833: throw new SocketException("socket is closed"); 834: 835: getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on)); 836: } 837: 838: /** 839: * Checks if SO_REUSEADDR is enabled. 840: * 841: * @return True if SO_REUSEADDR is set on the socket, false otherwise. 842: * 843: * @exception SocketException If an error occurs. 844: * 845: * @since 1.4 846: */ 847: public boolean getReuseAddress() throws SocketException 848: { 849: if (isClosed()) 850: throw new SocketException("socket is closed"); 851: 852: Object buf = getImpl().getOption(SocketOptions.SO_REUSEADDR); 853: 854: if (buf instanceof Boolean) 855: return ((Boolean) buf).booleanValue(); 856: 857: throw new SocketException("unexpected type"); 858: } 859: 860: /** 861: * Enables/Disables SO_BROADCAST 862: * 863: * @param enable True if SO_BROADCAST should be enabled, false otherwise. 864: * 865: * @exception SocketException If an error occurs 866: * 867: * @since 1.4 868: */ 869: public void setBroadcast(boolean enable) throws SocketException 870: { 871: if (isClosed()) 872: throw new SocketException("socket is closed"); 873: 874: getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(enable)); 875: } 876: 877: /** 878: * Checks if SO_BROADCAST is enabled 879: * 880: * @return Whether SO_BROADCAST is set 881: * 882: * @exception SocketException If an error occurs 883: * 884: * @since 1.4 885: */ 886: public boolean getBroadcast() throws SocketException 887: { 888: if (isClosed()) 889: throw new SocketException("socket is closed"); 890: 891: Object buf = getImpl().getOption(SocketOptions.SO_BROADCAST); 892: 893: if (buf instanceof Boolean) 894: return ((Boolean) buf).booleanValue(); 895: 896: throw new SocketException("unexpected type"); 897: } 898: 899: /** 900: * Sets the traffic class value 901: * 902: * @param tc The traffic class 903: * 904: * @exception SocketException If an error occurs 905: * @exception IllegalArgumentException If tc value is illegal 906: * 907: * @see DatagramSocket#getTrafficClass() 908: * 909: * @since 1.4 910: */ 911: public void setTrafficClass(int tc) throws SocketException 912: { 913: if (isClosed()) 914: throw new SocketException("socket is closed"); 915: 916: if (tc < 0 || tc > 255) 917: throw new IllegalArgumentException(); 918: 919: getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc)); 920: } 921: 922: /** 923: * Returns the current traffic class 924: * 925: * @return The current traffic class. 926: * 927: * @see DatagramSocket#setTrafficClass(int tc) 928: * 929: * @exception SocketException If an error occurs 930: * 931: * @since 1.4 932: */ 933: public int getTrafficClass() throws SocketException 934: { 935: if (isClosed()) 936: throw new SocketException("socket is closed"); 937: 938: Object buf = getImpl().getOption(SocketOptions.IP_TOS); 939: 940: if (buf instanceof Integer) 941: return ((Integer) buf).intValue(); 942: 943: throw new SocketException("unexpected type"); 944: } 945: 946: /** 947: * Sets the datagram socket implementation factory for the application 948: * 949: * @param fac The factory to set 950: * 951: * @exception IOException If an error occurs 952: * @exception SocketException If the factory is already defined 953: * @exception SecurityException If a security manager exists and its 954: * checkSetFactory method doesn't allow the operation 955: */ 956: public static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac) 957: throws IOException 958: { 959: if (factory != null) 960: throw new SocketException("DatagramSocketImplFactory already defined"); 961: 962: SecurityManager sm = System.getSecurityManager(); 963: if (sm != null) 964: sm.checkSetFactory(); 965: 966: factory = fac; 967: } 968: }
GNU Classpath (0.95) |