GNU Classpath (0.19) | ||
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 IllegalArgumentException If address or port are invalid. 488: * @exception SecurityException If the caller is not allowed to send 489: * datagrams to or receive from this address and port. 490: * 491: * @since 1.2 492: */ 493: public void connect(InetAddress address, int port) 494: { 495: if (address == null) 496: throw new IllegalArgumentException("Connect address may not be null"); 497: 498: if ((port < 1) || (port > 65535)) 499: throw new IllegalArgumentException("Port number is illegal: " + port); 500: 501: SecurityManager sm = System.getSecurityManager(); 502: if (sm != null) 503: sm.checkConnect(address.getHostName(), port); 504: 505: try 506: { 507: getImpl().connect(address, port); 508: remoteAddress = address; 509: remotePort = port; 510: } 511: catch (SocketException e) 512: { 513: // This means simply not connected or connect not implemented. 514: } 515: } 516: 517: /** 518: * This method disconnects this socket from the address/port it was 519: * connected to. If the socket was not connected in the first place, 520: * this method does nothing. 521: * 522: * @since 1.2 523: */ 524: public void disconnect() 525: { 526: if (! isConnected()) 527: return; 528: 529: try 530: { 531: getImpl().disconnect(); 532: } 533: catch (SocketException e) 534: { 535: // This cannot happen as we are connected. 536: } 537: finally 538: { 539: remoteAddress = null; 540: remotePort = -1; 541: } 542: } 543: 544: /** 545: * Reads a datagram packet from the socket. Note that this method 546: * will block until a packet is received from the network. On return, 547: * the passed in <code>DatagramPacket</code> is populated with the data 548: * received and all the other information about the packet. 549: * 550: * @param p A <code>DatagramPacket</code> for storing the data 551: * 552: * @exception IOException If an error occurs. 553: * @exception SocketTimeoutException If setSoTimeout was previously called 554: * and the timeout has expired. 555: * @exception PortUnreachableException If the socket is connected to a 556: * currently unreachable destination. Note, there is no guarantee that the 557: * exception will be thrown. 558: * @exception IllegalBlockingModeException If this socket has an associated 559: * channel, and the channel is in non-blocking mode. 560: * @exception SecurityException If a security manager exists and its 561: * checkAccept method doesn't allow the receive. 562: */ 563: public synchronized void receive(DatagramPacket p) throws IOException 564: { 565: if (isClosed()) 566: throw new SocketException("socket is closed"); 567: 568: if (remoteAddress != null && remoteAddress.isMulticastAddress()) 569: throw new IOException 570: ("Socket connected to a multicast address my not receive"); 571: 572: if (getChannel() != null && ! getChannel().isBlocking() 573: && ! ((DatagramChannelImpl) getChannel()).isInChannelOperation()) 574: throw new IllegalBlockingModeException(); 575: 576: getImpl().receive(p); 577: 578: SecurityManager s = System.getSecurityManager(); 579: if (s != null && isConnected()) 580: s.checkAccept(p.getAddress().getHostName(), p.getPort()); 581: } 582: 583: /** 584: * Sends the specified packet. The host and port to which the packet 585: * are to be sent should be set inside the packet. 586: * 587: * @param p The datagram packet to send. 588: * 589: * @exception IOException If an error occurs. 590: * @exception SecurityException If a security manager exists and its 591: * checkMulticast or checkConnect method doesn't allow the send. 592: * @exception PortUnreachableException If the socket is connected to a 593: * currently unreachable destination. Note, there is no guarantee that the 594: * exception will be thrown. 595: * @exception IllegalBlockingModeException If this socket has an associated 596: * channel, and the channel is in non-blocking mode. 597: */ 598: public void send(DatagramPacket p) throws IOException 599: { 600: if (isClosed()) 601: throw new SocketException("socket is closed"); 602: 603: // JDK1.2: Don't do security checks if socket is connected; see jdk1.2 api. 604: SecurityManager s = System.getSecurityManager(); 605: if (s != null && ! isConnected()) 606: { 607: InetAddress addr = p.getAddress(); 608: if (addr.isMulticastAddress()) 609: s.checkMulticast(addr); 610: else 611: s.checkConnect(addr.getHostAddress(), p.getPort()); 612: } 613: 614: if (isConnected()) 615: { 616: if (p.getAddress() != null 617: && (remoteAddress != p.getAddress() || remotePort != p.getPort())) 618: throw new IllegalArgumentException 619: ("DatagramPacket address does not match remote address"); 620: } 621: 622: // FIXME: if this is a subclass of MulticastSocket, 623: // use getTimeToLive for TTL val. 624: if (getChannel() != null && ! getChannel().isBlocking() 625: && ! ((DatagramChannelImpl) getChannel()).isInChannelOperation()) 626: throw new IllegalBlockingModeException(); 627: 628: getImpl().send(p); 629: } 630: 631: /** 632: * Binds the socket to the given socket address. 633: * 634: * @param address The socket address to bind to. 635: * 636: * @exception SocketException If an error occurs. 637: * @exception SecurityException If a security manager exists and 638: * its checkListen method doesn't allow the operation. 639: * @exception IllegalArgumentException If address type is not supported. 640: * 641: * @since 1.4 642: */ 643: public void bind(SocketAddress address) throws SocketException 644: { 645: if (isClosed()) 646: throw new SocketException("socket is closed"); 647: 648: if (! (address instanceof InetSocketAddress)) 649: throw new IllegalArgumentException("unsupported address type"); 650: 651: InetAddress addr = ((InetSocketAddress) address).getAddress(); 652: int port = ((InetSocketAddress) address).getPort(); 653: 654: if (port < 0 || port > 65535) 655: throw new IllegalArgumentException("Invalid port: " + port); 656: 657: SecurityManager s = System.getSecurityManager(); 658: if (s != null) 659: s.checkListen(port); 660: 661: if (addr == null) 662: addr = InetAddress.ANY_IF; 663: 664: try 665: { 666: getImpl().bind(port, addr); 667: bound = true; 668: } 669: catch (SocketException exception) 670: { 671: getImpl().close(); 672: throw exception; 673: } 674: catch (RuntimeException exception) 675: { 676: getImpl().close(); 677: throw exception; 678: } 679: catch (Error error) 680: { 681: getImpl().close(); 682: throw error; 683: } 684: } 685: 686: /** 687: * Checks if the datagram socket is closed. 688: * 689: * @return True if socket is closed, false otherwise. 690: * 691: * @since 1.4 692: */ 693: public boolean isClosed() 694: { 695: return impl == null; 696: } 697: 698: /** 699: * Returns the datagram channel assoziated with this datagram socket. 700: * 701: * @return The associated <code>DatagramChannel</code> object or null 702: * 703: * @since 1.4 704: */ 705: public DatagramChannel getChannel() 706: { 707: return null; 708: } 709: 710: /** 711: * Connects the datagram socket to a specified socket address. 712: * 713: * @param address The socket address to connect to. 714: * 715: * @exception SocketException If an error occurs. 716: * @exception IllegalArgumentException If address type is not supported. 717: * 718: * @since 1.4 719: */ 720: public void connect(SocketAddress address) throws SocketException 721: { 722: if (isClosed()) 723: throw new SocketException("socket is closed"); 724: 725: if (! (address instanceof InetSocketAddress)) 726: throw new IllegalArgumentException("unsupported address type"); 727: 728: InetSocketAddress tmp = (InetSocketAddress) address; 729: connect(tmp.getAddress(), tmp.getPort()); 730: } 731: 732: /** 733: * Returns the binding state of the socket. 734: * 735: * @return True if socket bound, false otherwise. 736: * 737: * @since 1.4 738: */ 739: public boolean isBound() 740: { 741: return bound; 742: } 743: 744: /** 745: * Returns the connection state of the socket. 746: * 747: * @return True if socket is connected, false otherwise. 748: * 749: * @since 1.4 750: */ 751: public boolean isConnected() 752: { 753: return remoteAddress != null; 754: } 755: 756: /** 757: * Returns the SocketAddress of the host this socket is conneted to 758: * or null if this socket is not connected. 759: * 760: * @return The socket address of the remote host if connected or null 761: * 762: * @since 1.4 763: */ 764: public SocketAddress getRemoteSocketAddress() 765: { 766: if (! isConnected()) 767: return null; 768: 769: return new InetSocketAddress(remoteAddress, remotePort); 770: } 771: 772: /** 773: * Returns the local SocketAddress this socket is bound to. 774: * 775: * @return The local SocketAddress or null if the socket is not bound. 776: * 777: * @since 1.4 778: */ 779: public SocketAddress getLocalSocketAddress() 780: { 781: if (! isBound()) 782: return null; 783: 784: return new InetSocketAddress(getLocalAddress(), getLocalPort()); 785: } 786: 787: /** 788: * Enables/Disables SO_REUSEADDR. 789: * 790: * @param on Whether or not to have SO_REUSEADDR turned on. 791: * 792: * @exception SocketException If an error occurs. 793: * 794: * @since 1.4 795: */ 796: public void setReuseAddress(boolean on) throws SocketException 797: { 798: if (isClosed()) 799: throw new SocketException("socket is closed"); 800: 801: getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on)); 802: } 803: 804: /** 805: * Checks if SO_REUSEADDR is enabled. 806: * 807: * @return True if SO_REUSEADDR is set on the socket, false otherwise. 808: * 809: * @exception SocketException If an error occurs. 810: * 811: * @since 1.4 812: */ 813: public boolean getReuseAddress() throws SocketException 814: { 815: if (isClosed()) 816: throw new SocketException("socket is closed"); 817: 818: Object buf = getImpl().getOption(SocketOptions.SO_REUSEADDR); 819: 820: if (buf instanceof Boolean) 821: return ((Boolean) buf).booleanValue(); 822: 823: throw new SocketException("unexpected type"); 824: } 825: 826: /** 827: * Enables/Disables SO_BROADCAST 828: * 829: * @param enable True if SO_BROADCAST should be enabled, false otherwise. 830: * 831: * @exception SocketException If an error occurs 832: * 833: * @since 1.4 834: */ 835: public void setBroadcast(boolean enable) throws SocketException 836: { 837: if (isClosed()) 838: throw new SocketException("socket is closed"); 839: 840: getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(enable)); 841: } 842: 843: /** 844: * Checks if SO_BROADCAST is enabled 845: * 846: * @return Whether SO_BROADCAST is set 847: * 848: * @exception SocketException If an error occurs 849: * 850: * @since 1.4 851: */ 852: public boolean getBroadcast() throws SocketException 853: { 854: if (isClosed()) 855: throw new SocketException("socket is closed"); 856: 857: Object buf = getImpl().getOption(SocketOptions.SO_BROADCAST); 858: 859: if (buf instanceof Boolean) 860: return ((Boolean) buf).booleanValue(); 861: 862: throw new SocketException("unexpected type"); 863: } 864: 865: /** 866: * Sets the traffic class value 867: * 868: * @param tc The traffic class 869: * 870: * @exception SocketException If an error occurs 871: * @exception IllegalArgumentException If tc value is illegal 872: * 873: * @see DatagramSocket#getTrafficClass() 874: * 875: * @since 1.4 876: */ 877: public void setTrafficClass(int tc) throws SocketException 878: { 879: if (isClosed()) 880: throw new SocketException("socket is closed"); 881: 882: if (tc < 0 || tc > 255) 883: throw new IllegalArgumentException(); 884: 885: getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc)); 886: } 887: 888: /** 889: * Returns the current traffic class 890: * 891: * @return The current traffic class. 892: * 893: * @see DatagramSocket#setTrafficClass(int tc) 894: * 895: * @exception SocketException If an error occurs 896: * 897: * @since 1.4 898: */ 899: public int getTrafficClass() throws SocketException 900: { 901: if (isClosed()) 902: throw new SocketException("socket is closed"); 903: 904: Object buf = getImpl().getOption(SocketOptions.IP_TOS); 905: 906: if (buf instanceof Integer) 907: return ((Integer) buf).intValue(); 908: 909: throw new SocketException("unexpected type"); 910: } 911: 912: /** 913: * Sets the datagram socket implementation factory for the application 914: * 915: * @param fac The factory to set 916: * 917: * @exception IOException If an error occurs 918: * @exception SocketException If the factory is already defined 919: * @exception SecurityException If a security manager exists and its 920: * checkSetFactory method doesn't allow the operation 921: */ 922: public static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac) 923: throws IOException 924: { 925: if (factory != null) 926: throw new SocketException("DatagramSocketImplFactory already defined"); 927: 928: SecurityManager sm = System.getSecurityManager(); 929: if (sm != null) 930: sm.checkSetFactory(); 931: 932: factory = fac; 933: } 934: }
GNU Classpath (0.19) |