GNU Classpath (0.18) | ||
Frames | No Frames |
1: /* DatagramSocket.java -- A class to model UDP sockets 2: Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005 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: impl = new PlainDatagramSocketImpl(); 180: else 181: try 182: { 183: impl = 184: (DatagramSocketImpl) Class.forName("java.net." + propVal 185: + "DatagramSocketImpl") 186: .newInstance(); 187: } 188: catch (Exception e) 189: { 190: System.err.println("Could not instantiate class: java.net." 191: + propVal + "DatagramSocketImpl"); 192: impl = new PlainDatagramSocketImpl(); 193: } 194: 195: if (address != null) 196: bind(address); 197: } 198: 199: // This needs to be accessible from java.net.MulticastSocket 200: DatagramSocketImpl getImpl() throws SocketException 201: { 202: try 203: { 204: if (! implCreated) 205: { 206: impl.create(); 207: implCreated = true; 208: } 209: 210: return impl; 211: } 212: catch (IOException e) 213: { 214: SocketException se = new SocketException(); 215: se.initCause(e); 216: throw se; 217: } 218: } 219: 220: /** 221: * Closes this datagram socket. 222: */ 223: public void close() 224: { 225: if (isClosed()) 226: return; 227: 228: try 229: { 230: getImpl().close(); 231: } 232: catch (SocketException e) 233: { 234: // Ignore this case, just close the socket in finally clause. 235: } 236: finally 237: { 238: remoteAddress = null; 239: remotePort = -1; 240: impl = null; 241: } 242: 243: try 244: { 245: if (getChannel() != null) 246: getChannel().close(); 247: } 248: catch (IOException e) 249: { 250: // Do nothing. 251: } 252: } 253: 254: /** 255: * This method returns the remote address to which this socket is 256: * connected. If this socket is not connected, then this method will 257: * return <code>null</code>. 258: * 259: * @return The remote address. 260: * 261: * @since 1.2 262: */ 263: public InetAddress getInetAddress() 264: { 265: return remoteAddress; 266: } 267: 268: /** 269: * This method returns the remote port to which this socket is 270: * connected. If this socket is not connected, then this method will 271: * return -1. 272: * 273: * @return The remote port. 274: * 275: * @since 1.2 276: */ 277: public int getPort() 278: { 279: return remotePort; 280: } 281: 282: /** 283: * Returns the local address this datagram socket is bound to. 284: * 285: * @return The local address is the socket is bound or null 286: * 287: * @since 1.1 288: */ 289: public InetAddress getLocalAddress() 290: { 291: if (! isBound()) 292: return null; 293: 294: InetAddress localAddr; 295: 296: try 297: { 298: localAddr = 299: (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR); 300: 301: SecurityManager s = System.getSecurityManager(); 302: if (s != null) 303: s.checkConnect(localAddr.getHostName(), -1); 304: } 305: catch (SecurityException e) 306: { 307: localAddr = InetAddress.ANY_IF; 308: } 309: catch (SocketException e) 310: { 311: // This cannot happen as we are bound. 312: return null; 313: } 314: 315: return localAddr; 316: } 317: 318: /** 319: * Returns the local port this socket is bound to. 320: * 321: * @return The local port number. 322: */ 323: public int getLocalPort() 324: { 325: if (isClosed()) 326: return -1; 327: 328: try 329: { 330: return getImpl().getLocalPort(); 331: } 332: catch (SocketException e) 333: { 334: // This cannot happen as we are bound. 335: return 0; 336: } 337: } 338: 339: /** 340: * Returns the value of the socket's SO_TIMEOUT setting. If this method 341: * returns 0 then SO_TIMEOUT is disabled. 342: * 343: * @return The current timeout in milliseconds. 344: * 345: * @exception SocketException If an error occurs. 346: * 347: * @since 1.1 348: */ 349: public synchronized int getSoTimeout() throws SocketException 350: { 351: if (isClosed()) 352: throw new SocketException("socket is closed"); 353: 354: Object buf = getImpl().getOption(SocketOptions.SO_TIMEOUT); 355: 356: if (buf instanceof Integer) 357: return ((Integer) buf).intValue(); 358: 359: throw new SocketException("unexpected type"); 360: } 361: 362: /** 363: * Sets the value of the socket's SO_TIMEOUT value. A value of 0 will 364: * disable SO_TIMEOUT. Any other value is the number of milliseconds 365: * a socket read/write will block before timing out. 366: * 367: * @param timeout The new SO_TIMEOUT value in milliseconds. 368: * 369: * @exception SocketException If an error occurs. 370: * 371: * @since 1.1 372: */ 373: public synchronized void setSoTimeout(int timeout) throws SocketException 374: { 375: if (isClosed()) 376: throw new SocketException("socket is closed"); 377: 378: if (timeout < 0) 379: throw new IllegalArgumentException("Invalid timeout: " + timeout); 380: 381: getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout)); 382: } 383: 384: /** 385: * This method returns the value of the system level socket option 386: * SO_SNDBUF, which is used by the operating system to tune buffer 387: * sizes for data transfers. 388: * 389: * @return The send buffer size. 390: * 391: * @exception SocketException If an error occurs. 392: * 393: * @since 1.2 394: */ 395: public int getSendBufferSize() throws SocketException 396: { 397: if (isClosed()) 398: throw new SocketException("socket is closed"); 399: 400: Object buf = getImpl().getOption(SocketOptions.SO_SNDBUF); 401: 402: if (buf instanceof Integer) 403: return ((Integer) buf).intValue(); 404: 405: throw new SocketException("unexpected type"); 406: } 407: 408: /** 409: * This method sets the value for the system level socket option 410: * SO_SNDBUF to the specified value. Note that valid values for this 411: * option are specific to a given operating system. 412: * 413: * @param size The new send buffer size. 414: * 415: * @exception SocketException If an error occurs. 416: * @exception IllegalArgumentException If size is 0 or negative. 417: * 418: * @since 1.2 419: */ 420: public void setSendBufferSize(int size) throws SocketException 421: { 422: if (isClosed()) 423: throw new SocketException("socket is closed"); 424: 425: if (size < 0) 426: throw new IllegalArgumentException("Buffer size is less than 0"); 427: 428: getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size)); 429: } 430: 431: /** 432: * This method returns the value of the system level socket option 433: * SO_RCVBUF, which is used by the operating system to tune buffer 434: * sizes for data transfers. 435: * 436: * @return The receive buffer size. 437: * 438: * @exception SocketException If an error occurs. 439: * 440: * @since 1.2 441: */ 442: public int getReceiveBufferSize() throws SocketException 443: { 444: if (isClosed()) 445: throw new SocketException("socket is closed"); 446: 447: Object buf = getImpl().getOption(SocketOptions.SO_RCVBUF); 448: 449: if (buf instanceof Integer) 450: return ((Integer) buf).intValue(); 451: 452: throw new SocketException("unexpected type"); 453: } 454: 455: /** 456: * This method sets the value for the system level socket option 457: * SO_RCVBUF to the specified value. Note that valid values for this 458: * option are specific to a given operating system. 459: * 460: * @param size The new receive buffer size. 461: * 462: * @exception SocketException If an error occurs. 463: * @exception IllegalArgumentException If size is 0 or negative. 464: * 465: * @since 1.2 466: */ 467: public void setReceiveBufferSize(int size) throws SocketException 468: { 469: if (isClosed()) 470: throw new SocketException("socket is closed"); 471: 472: if (size < 0) 473: throw new IllegalArgumentException("Buffer size is less than 0"); 474: 475: getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size)); 476: } 477: 478: /** 479: * This method connects this socket to the specified address and port. 480: * When a datagram socket is connected, it will only send or receive 481: * packets to and from the host to which it is connected. A multicast 482: * socket that is connected may only send and not receive packets. 483: * 484: * @param address The address to connect this socket to. 485: * @param port The port to connect this socket to. 486: * 487: * @exception SocketException If an error occurs. 488: * @exception IllegalArgumentException If address or port are invalid. 489: * @exception SecurityException If the caller is not allowed to send 490: * datagrams to or receive from this address and port. 491: * 492: * @since 1.2 493: */ 494: public void connect(InetAddress address, int port) 495: { 496: if (address == null) 497: throw new IllegalArgumentException("Connect address may not be null"); 498: 499: if ((port < 1) || (port > 65535)) 500: throw new IllegalArgumentException("Port number is illegal: " + port); 501: 502: SecurityManager sm = System.getSecurityManager(); 503: if (sm != null) 504: sm.checkConnect(address.getHostName(), port); 505: 506: try 507: { 508: getImpl().connect(address, port); 509: remoteAddress = address; 510: remotePort = port; 511: } 512: catch (SocketException e) 513: { 514: // This means simply not connected or connect not implemented. 515: } 516: } 517: 518: /** 519: * This method disconnects this socket from the address/port it was 520: * connected to. If the socket was not connected in the first place, 521: * this method does nothing. 522: * 523: * @since 1.2 524: */ 525: public void disconnect() 526: { 527: if (! isConnected()) 528: return; 529: 530: try 531: { 532: getImpl().disconnect(); 533: } 534: catch (SocketException e) 535: { 536: // This cannot happen as we are connected. 537: } 538: finally 539: { 540: remoteAddress = null; 541: remotePort = -1; 542: } 543: } 544: 545: /** 546: * Reads a datagram packet from the socket. Note that this method 547: * will block until a packet is received from the network. On return, 548: * the passed in <code>DatagramPacket</code> is populated with the data 549: * received and all the other information about the packet. 550: * 551: * @param p A <code>DatagramPacket</code> for storing the data 552: * 553: * @exception IOException If an error occurs. 554: * @exception SocketTimeoutException If setSoTimeout was previously called 555: * and the timeout has expired. 556: * @exception PortUnreachableException If the socket is connected to a 557: * currently unreachable destination. Note, there is no guarantee that the 558: * exception will be thrown. 559: * @exception IllegalBlockingModeException If this socket has an associated 560: * channel, and the channel is in non-blocking mode. 561: * @exception SecurityException If a security manager exists and its 562: * checkAccept method doesn't allow the receive. 563: */ 564: public synchronized void receive(DatagramPacket p) throws IOException 565: { 566: if (isClosed()) 567: throw new SocketException("socket is closed"); 568: 569: if (remoteAddress != null && remoteAddress.isMulticastAddress()) 570: throw new IOException 571: ("Socket connected to a multicast address my not receive"); 572: 573: if (getChannel() != null && ! getChannel().isBlocking() 574: && ! ((DatagramChannelImpl) getChannel()).isInChannelOperation()) 575: throw new IllegalBlockingModeException(); 576: 577: getImpl().receive(p); 578: 579: SecurityManager s = System.getSecurityManager(); 580: if (s != null && isConnected()) 581: s.checkAccept(p.getAddress().getHostName(), p.getPort()); 582: } 583: 584: /** 585: * Sends the specified packet. The host and port to which the packet 586: * are to be sent should be set inside the packet. 587: * 588: * @param p The datagram packet to send. 589: * 590: * @exception IOException If an error occurs. 591: * @exception SecurityException If a security manager exists and its 592: * checkMulticast or checkConnect method doesn't allow the send. 593: * @exception PortUnreachableException If the socket is connected to a 594: * currently unreachable destination. Note, there is no guarantee that the 595: * exception will be thrown. 596: * @exception IllegalBlockingModeException If this socket has an associated 597: * channel, and the channel is in non-blocking mode. 598: */ 599: public void send(DatagramPacket p) throws IOException 600: { 601: if (isClosed()) 602: throw new SocketException("socket is closed"); 603: 604: // JDK1.2: Don't do security checks if socket is connected; see jdk1.2 api. 605: SecurityManager s = System.getSecurityManager(); 606: if (s != null && ! isConnected()) 607: { 608: InetAddress addr = p.getAddress(); 609: if (addr.isMulticastAddress()) 610: s.checkMulticast(addr); 611: else 612: s.checkConnect(addr.getHostAddress(), p.getPort()); 613: } 614: 615: if (isConnected()) 616: { 617: if (p.getAddress() != null 618: && (remoteAddress != p.getAddress() || remotePort != p.getPort())) 619: throw new IllegalArgumentException 620: ("DatagramPacket address does not match remote address"); 621: } 622: 623: // FIXME: if this is a subclass of MulticastSocket, 624: // use getTimeToLive for TTL val. 625: if (getChannel() != null && ! getChannel().isBlocking() 626: && ! ((DatagramChannelImpl) getChannel()).isInChannelOperation()) 627: throw new IllegalBlockingModeException(); 628: 629: getImpl().send(p); 630: } 631: 632: /** 633: * Binds the socket to the given socket address. 634: * 635: * @param address The socket address to bind to. 636: * 637: * @exception SocketException If an error occurs. 638: * @exception SecurityException If a security manager exists and 639: * its checkListen method doesn't allow the operation. 640: * @exception IllegalArgumentException If address type is not supported. 641: * 642: * @since 1.4 643: */ 644: public void bind(SocketAddress address) throws SocketException 645: { 646: if (isClosed()) 647: throw new SocketException("socket is closed"); 648: 649: if (! (address instanceof InetSocketAddress)) 650: throw new IllegalArgumentException("unsupported address type"); 651: 652: InetAddress addr = ((InetSocketAddress) address).getAddress(); 653: int port = ((InetSocketAddress) address).getPort(); 654: 655: if (port < 0 || port > 65535) 656: throw new IllegalArgumentException("Invalid port: " + port); 657: 658: SecurityManager s = System.getSecurityManager(); 659: if (s != null) 660: s.checkListen(port); 661: 662: if (addr == null) 663: addr = InetAddress.ANY_IF; 664: 665: try 666: { 667: getImpl().bind(port, addr); 668: bound = true; 669: } 670: catch (SocketException exception) 671: { 672: getImpl().close(); 673: throw exception; 674: } 675: catch (RuntimeException exception) 676: { 677: getImpl().close(); 678: throw exception; 679: } 680: catch (Error error) 681: { 682: getImpl().close(); 683: throw error; 684: } 685: } 686: 687: /** 688: * Checks if the datagram socket is closed. 689: * 690: * @return True if socket is closed, false otherwise. 691: * 692: * @since 1.4 693: */ 694: public boolean isClosed() 695: { 696: return impl == null; 697: } 698: 699: /** 700: * Returns the datagram channel assoziated with this datagram socket. 701: * 702: * @return The associated <code>DatagramChannel</code> object or null 703: * 704: * @since 1.4 705: */ 706: public DatagramChannel getChannel() 707: { 708: return null; 709: } 710: 711: /** 712: * Connects the datagram socket to a specified socket address. 713: * 714: * @param address The socket address to connect to. 715: * 716: * @exception SocketException If an error occurs. 717: * @exception IllegalArgumentException If address type is not supported. 718: * 719: * @since 1.4 720: */ 721: public void connect(SocketAddress address) throws SocketException 722: { 723: if (isClosed()) 724: throw new SocketException("socket is closed"); 725: 726: if (! (address instanceof InetSocketAddress)) 727: throw new IllegalArgumentException("unsupported address type"); 728: 729: InetSocketAddress tmp = (InetSocketAddress) address; 730: connect(tmp.getAddress(), tmp.getPort()); 731: } 732: 733: /** 734: * Returns the binding state of the socket. 735: * 736: * @return True if socket bound, false otherwise. 737: * 738: * @since 1.4 739: */ 740: public boolean isBound() 741: { 742: return bound; 743: } 744: 745: /** 746: * Returns the connection state of the socket. 747: * 748: * @return True if socket is connected, false otherwise. 749: * 750: * @since 1.4 751: */ 752: public boolean isConnected() 753: { 754: return remoteAddress != null; 755: } 756: 757: /** 758: * Returns the SocketAddress of the host this socket is conneted to 759: * or null if this socket is not connected. 760: * 761: * @return The socket address of the remote host if connected or null 762: * 763: * @since 1.4 764: */ 765: public SocketAddress getRemoteSocketAddress() 766: { 767: if (! isConnected()) 768: return null; 769: 770: return new InetSocketAddress(remoteAddress, remotePort); 771: } 772: 773: /** 774: * Returns the local SocketAddress this socket is bound to. 775: * 776: * @return The local SocketAddress or null if the socket is not bound. 777: * 778: * @since 1.4 779: */ 780: public SocketAddress getLocalSocketAddress() 781: { 782: if (! isBound()) 783: return null; 784: 785: return new InetSocketAddress(getLocalAddress(), getLocalPort()); 786: } 787: 788: /** 789: * Enables/Disables SO_REUSEADDR. 790: * 791: * @param on Whether or not to have SO_REUSEADDR turned on. 792: * 793: * @exception SocketException If an error occurs. 794: * 795: * @since 1.4 796: */ 797: public void setReuseAddress(boolean on) throws SocketException 798: { 799: if (isClosed()) 800: throw new SocketException("socket is closed"); 801: 802: getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on)); 803: } 804: 805: /** 806: * Checks if SO_REUSEADDR is enabled. 807: * 808: * @return True if SO_REUSEADDR is set on the socket, false otherwise. 809: * 810: * @exception SocketException If an error occurs. 811: * 812: * @since 1.4 813: */ 814: public boolean getReuseAddress() throws SocketException 815: { 816: if (isClosed()) 817: throw new SocketException("socket is closed"); 818: 819: Object buf = getImpl().getOption(SocketOptions.SO_REUSEADDR); 820: 821: if (buf instanceof Boolean) 822: return ((Boolean) buf).booleanValue(); 823: 824: throw new SocketException("unexpected type"); 825: } 826: 827: /** 828: * Enables/Disables SO_BROADCAST 829: * 830: * @param enable True if SO_BROADCAST should be enabled, false otherwise. 831: * 832: * @exception SocketException If an error occurs 833: * 834: * @since 1.4 835: */ 836: public void setBroadcast(boolean enable) throws SocketException 837: { 838: if (isClosed()) 839: throw new SocketException("socket is closed"); 840: 841: getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(enable)); 842: } 843: 844: /** 845: * Checks if SO_BROADCAST is enabled 846: * 847: * @return Whether SO_BROADCAST is set 848: * 849: * @exception SocketException If an error occurs 850: * 851: * @since 1.4 852: */ 853: public boolean getBroadcast() throws SocketException 854: { 855: if (isClosed()) 856: throw new SocketException("socket is closed"); 857: 858: Object buf = getImpl().getOption(SocketOptions.SO_BROADCAST); 859: 860: if (buf instanceof Boolean) 861: return ((Boolean) buf).booleanValue(); 862: 863: throw new SocketException("unexpected type"); 864: } 865: 866: /** 867: * Sets the traffic class value 868: * 869: * @param tc The traffic class 870: * 871: * @exception SocketException If an error occurs 872: * @exception IllegalArgumentException If tc value is illegal 873: * 874: * @see DatagramSocket#getTrafficClass() 875: * 876: * @since 1.4 877: */ 878: public void setTrafficClass(int tc) throws SocketException 879: { 880: if (isClosed()) 881: throw new SocketException("socket is closed"); 882: 883: if (tc < 0 || tc > 255) 884: throw new IllegalArgumentException(); 885: 886: getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc)); 887: } 888: 889: /** 890: * Returns the current traffic class 891: * 892: * @return The current traffic class. 893: * 894: * @see DatagramSocket#setTrafficClass(int tc) 895: * 896: * @exception SocketException If an error occurs 897: * 898: * @since 1.4 899: */ 900: public int getTrafficClass() throws SocketException 901: { 902: if (isClosed()) 903: throw new SocketException("socket is closed"); 904: 905: Object buf = getImpl().getOption(SocketOptions.IP_TOS); 906: 907: if (buf instanceof Integer) 908: return ((Integer) buf).intValue(); 909: 910: throw new SocketException("unexpected type"); 911: } 912: 913: /** 914: * Sets the datagram socket implementation factory for the application 915: * 916: * @param fac The factory to set 917: * 918: * @exception IOException If an error occurs 919: * @exception SocketException If the factory is already defined 920: * @exception SecurityException If a security manager exists and its 921: * checkSetFactory method doesn't allow the operation 922: */ 923: public static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac) 924: throws IOException 925: { 926: if (factory != null) 927: throw new SocketException("DatagramSocketImplFactory already defined"); 928: 929: SecurityManager sm = System.getSecurityManager(); 930: if (sm != null) 931: sm.checkSetFactory(); 932: 933: factory = fac; 934: } 935: }
GNU Classpath (0.18) |