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