GNU Classpath (0.20) | |
Frames | No Frames |
1: /* MulticastSocket.java -- Class for using multicast sockets 2: Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 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 java.io.IOException; 42: import java.util.Enumeration; 43: 44: 45: /** 46: * Written using on-line Java Platform 1.2 API Specification, as well 47: * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). 48: * Status: Believed complete and correct. 49: */ 50: /** 51: * This class models a multicast UDP socket. A multicast address is a 52: * class D internet address (one whose most significant bits are 1110). 53: * A multicast group consists of a multicast address and a well known 54: * port number. All members of the group listening on that address and 55: * port will receive all the broadcasts to the group. 56: * <p> 57: * Please note that applets are not allowed to use multicast sockets 58: * 59: * Written using on-line Java Platform 1.2 API Specification, as well 60: * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998). 61: * Status: Believed complete and correct. 62: * 63: * @author Warren Levy (warrenl@cygnus.com) 64: * @author Aaron M. Renn (arenn@urbanophile.com) (Documentation comments) 65: * @since 1.1 66: * @date May 18, 1999. 67: */ 68: public class MulticastSocket extends DatagramSocket 69: { 70: /** 71: * Create a MulticastSocket that this not bound to any address 72: * 73: * @exception IOException If an error occurs 74: * @exception SecurityException If a security manager exists and its 75: * checkListen method doesn't allow the operation 76: */ 77: public MulticastSocket() throws IOException 78: { 79: this(new InetSocketAddress(0)); 80: } 81: 82: /** 83: * Create a multicast socket bound to the specified port 84: * 85: * @param port The port to bind to 86: * 87: * @exception IOException If an error occurs 88: * @exception SecurityException If a security manager exists and its 89: * checkListen method doesn't allow the operation 90: */ 91: public MulticastSocket(int port) throws IOException 92: { 93: this(new InetSocketAddress(port)); 94: } 95: 96: /** 97: * Create a multicast socket bound to the specified SocketAddress. 98: * 99: * @param address The SocketAddress the multicast socket will be bound to 100: * 101: * @exception IOException If an error occurs 102: * @exception SecurityException If a security manager exists and its 103: * checkListen method doesn't allow the operation 104: * 105: * @since 1.4 106: */ 107: public MulticastSocket(SocketAddress address) throws IOException 108: { 109: super((SocketAddress) null); 110: setReuseAddress(true); 111: if (address != null) 112: bind(address); 113: } 114: 115: /** 116: * Returns the interface being used for multicast packets 117: * 118: * @return The multicast interface 119: * 120: * @exception SocketException If an error occurs 121: */ 122: public InetAddress getInterface() throws SocketException 123: { 124: if (isClosed()) 125: throw new SocketException("socket is closed"); 126: 127: return (InetAddress) getImpl().getOption(SocketOptions.IP_MULTICAST_IF); 128: } 129: 130: /** 131: * Returns the current value of the "Time to Live" option. This is the 132: * number of hops a packet can make before it "expires". This method id 133: * deprecated. Use <code>getTimeToLive</code> instead. 134: * 135: * @return The TTL value 136: * 137: * @exception IOException If an error occurs 138: * 139: * @deprecated 1.2 Replaced by getTimeToLive() 140: * 141: * @see MulticastSocket#getTimeToLive() 142: */ 143: public byte getTTL() throws IOException 144: { 145: if (isClosed()) 146: throw new SocketException("socket is closed"); 147: 148: // Use getTTL here rather than getTimeToLive in case we're using an impl 149: // other than the default PlainDatagramSocketImpl and it doesn't have 150: // getTimeToLive yet. 151: return getImpl().getTTL(); 152: } 153: 154: /** 155: * Returns the current value of the "Time to Live" option. This is the 156: * number of hops a packet can make before it "expires". 157: * 158: * @return The TTL value 159: * 160: * @exception IOException If an error occurs 161: * 162: * @since 1.2 163: */ 164: public int getTimeToLive() throws IOException 165: { 166: if (isClosed()) 167: throw new SocketException("socket is closed"); 168: 169: return getImpl().getTimeToLive(); 170: } 171: 172: /** 173: * Sets the interface to use for sending multicast packets. 174: * 175: * @param addr The new interface to use. 176: * 177: * @exception SocketException If an error occurs. 178: * 179: * @since 1.4 180: */ 181: public void setInterface(InetAddress addr) throws SocketException 182: { 183: if (isClosed()) 184: throw new SocketException("socket is closed"); 185: 186: getImpl().setOption(SocketOptions.IP_MULTICAST_IF, addr); 187: } 188: 189: /** 190: * Sets the local network interface used to send multicast messages 191: * 192: * @param netIf The local network interface used to send multicast messages 193: * 194: * @exception SocketException If an error occurs 195: * 196: * @see MulticastSocket#getNetworkInterface() 197: * 198: * @since 1.4 199: */ 200: public void setNetworkInterface(NetworkInterface netIf) 201: throws SocketException 202: { 203: if (isClosed()) 204: throw new SocketException("socket is closed"); 205: 206: Enumeration e = netIf.getInetAddresses(); 207: 208: if (! e.hasMoreElements()) 209: throw new SocketException("no network devices found"); 210: 211: InetAddress address = (InetAddress) e.nextElement(); 212: getImpl().setOption(SocketOptions.IP_MULTICAST_IF, address); 213: } 214: 215: /** 216: * Gets the local network interface which is used to send multicast messages 217: * 218: * @return The local network interface to send multicast messages 219: * 220: * @exception SocketException If an error occurs 221: * 222: * @see MulticastSocket#setNetworkInterface(NetworkInterface netIf) 223: * 224: * @since 1.4 225: */ 226: public NetworkInterface getNetworkInterface() throws SocketException 227: { 228: if (isClosed()) 229: throw new SocketException("socket is closed"); 230: 231: InetAddress address = 232: (InetAddress) getImpl().getOption(SocketOptions.IP_MULTICAST_IF); 233: NetworkInterface netIf = NetworkInterface.getByInetAddress(address); 234: 235: return netIf; 236: } 237: 238: /** 239: * Disable/Enable local loopback of multicast packets. The option is used by 240: * the platform's networking code as a hint for setting whether multicast 241: * data will be looped back to the local socket. 242: * 243: * Because this option is a hint, applications that want to verify what 244: * loopback mode is set to should call #getLoopbackMode 245: * 246: * @param disable True to disable loopback mode 247: * 248: * @exception SocketException If an error occurs 249: * 250: * @since 1.4 251: */ 252: public void setLoopbackMode(boolean disable) throws SocketException 253: { 254: if (isClosed()) 255: throw new SocketException("socket is closed"); 256: 257: getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP, 258: Boolean.valueOf(disable)); 259: } 260: 261: /** 262: * Checks if local loopback mode is enabled 263: * 264: * @return true if loopback mode is enabled, false otherwise 265: * 266: * @exception SocketException If an error occurs 267: * 268: * @since 1.4 269: */ 270: public boolean getLoopbackMode() throws SocketException 271: { 272: if (isClosed()) 273: throw new SocketException("socket is closed"); 274: 275: Object buf = getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP); 276: 277: if (buf instanceof Boolean) 278: return ((Boolean) buf).booleanValue(); 279: 280: throw new SocketException("unexpected type"); 281: } 282: 283: /** 284: * Sets the "Time to Live" value for a socket. The value must be between 285: * 1 and 255. 286: * 287: * @param ttl The new TTL value 288: * 289: * @exception IOException If an error occurs 290: * 291: * @deprecated 1.2 Replaced by <code>setTimeToLive</code> 292: * 293: * @see MulticastSocket#setTimeToLive(int ttl) 294: */ 295: public void setTTL(byte ttl) throws IOException 296: { 297: if (isClosed()) 298: throw new SocketException("socket is closed"); 299: 300: // Use setTTL here rather than setTimeToLive in case we're using an impl 301: // other than the default PlainDatagramSocketImpl and it doesn't have 302: // setTimeToLive yet. 303: getImpl().setTTL(ttl); 304: } 305: 306: /** 307: * Sets the "Time to Live" value for a socket. The value must be between 308: * 1 and 255. 309: * 310: * @param ttl The new TTL value 311: * 312: * @exception IOException If an error occurs 313: * 314: * @since 1.2 315: */ 316: public void setTimeToLive(int ttl) throws IOException 317: { 318: if (isClosed()) 319: throw new SocketException("socket is closed"); 320: 321: if (ttl <= 0 || ttl > 255) 322: throw new IllegalArgumentException("Invalid ttl: " + ttl); 323: 324: getImpl().setTimeToLive(ttl); 325: } 326: 327: /** 328: * Joins the specified multicast group. 329: * 330: * @param mcastaddr The address of the group to join 331: * 332: * @exception IOException If an error occurs 333: * @exception SecurityException If a security manager exists and its 334: * checkMulticast method doesn't allow the operation 335: */ 336: public void joinGroup(InetAddress mcastaddr) throws IOException 337: { 338: if (isClosed()) 339: throw new SocketException("socket is closed"); 340: 341: if (! mcastaddr.isMulticastAddress()) 342: throw new IOException("Not a Multicast address"); 343: 344: SecurityManager s = System.getSecurityManager(); 345: if (s != null) 346: s.checkMulticast(mcastaddr); 347: 348: getImpl().join(mcastaddr); 349: } 350: 351: /** 352: * Leaves the specified multicast group 353: * 354: * @param mcastaddr The address of the group to leave 355: * 356: * @exception IOException If an error occurs 357: * @exception SecurityException If a security manager exists and its 358: * checkMulticast method doesn't allow the operation 359: */ 360: public void leaveGroup(InetAddress mcastaddr) throws IOException 361: { 362: if (isClosed()) 363: throw new SocketException("socket is closed"); 364: 365: if (! mcastaddr.isMulticastAddress()) 366: throw new IOException("Not a Multicast address"); 367: 368: SecurityManager s = System.getSecurityManager(); 369: if (s != null) 370: s.checkMulticast(mcastaddr); 371: 372: getImpl().leave(mcastaddr); 373: } 374: 375: /** 376: * Joins the specified mulitcast group on a specified interface. 377: * 378: * @param mcastaddr The multicast address to join 379: * @param netIf The local network interface to receive the multicast 380: * messages on or null to defer the interface set by #setInterface or 381: * #setNetworkInterface 382: * 383: * @exception IOException If an error occurs 384: * @exception IllegalArgumentException If address type is not supported 385: * @exception SecurityException If a security manager exists and its 386: * checkMulticast method doesn't allow the operation 387: * 388: * @see MulticastSocket#setInterface(InetAddress addr) 389: * @see MulticastSocket#setNetworkInterface(NetworkInterface netIf) 390: * 391: * @since 1.4 392: */ 393: public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) 394: throws IOException 395: { 396: if (isClosed()) 397: throw new SocketException("socket is closed"); 398: 399: if (! (mcastaddr instanceof InetSocketAddress)) 400: throw new IllegalArgumentException("SocketAddress type not supported"); 401: 402: InetSocketAddress tmp = (InetSocketAddress) mcastaddr; 403: 404: if (! tmp.getAddress().isMulticastAddress()) 405: throw new IOException("Not a Multicast address"); 406: 407: SecurityManager s = System.getSecurityManager(); 408: if (s != null) 409: s.checkMulticast(tmp.getAddress()); 410: 411: getImpl().joinGroup(mcastaddr, netIf); 412: } 413: 414: /** 415: * Leaves the specified mulitcast group on a specified interface. 416: * 417: * @param mcastaddr The multicast address to leave 418: * @param netIf The local networki interface or null to defer to the 419: * interface set by setInterface or setNetworkInterface 420: * 421: * @exception IOException If an error occurs 422: * @exception IllegalArgumentException If address type is not supported 423: * @exception SecurityException If a security manager exists and its 424: * checkMulticast method doesn't allow the operation 425: * 426: * @see MulticastSocket#setInterface(InetAddress addr) 427: * @see MulticastSocket#setNetworkInterface(NetworkInterface netIf) 428: * 429: * @since 1.4 430: */ 431: public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) 432: throws IOException 433: { 434: if (isClosed()) 435: throw new SocketException("socket is closed"); 436: 437: InetSocketAddress tmp = (InetSocketAddress) mcastaddr; 438: 439: if (! tmp.getAddress().isMulticastAddress()) 440: throw new IOException("Not a Multicast address"); 441: 442: SecurityManager s = System.getSecurityManager(); 443: if (s != null) 444: s.checkMulticast(tmp.getAddress()); 445: 446: getImpl().leaveGroup(mcastaddr, netIf); 447: } 448: 449: /** 450: * Sends a packet of data to a multicast address with a TTL that is 451: * different from the default TTL on this socket. The default TTL for 452: * the socket is not changed. 453: * 454: * @param packet The packet of data to send 455: * @param ttl The TTL for this packet 456: * 457: * @exception IOException If an error occurs 458: * @exception SecurityException If a security manager exists and its 459: * checkConnect or checkMulticast method doesn't allow the operation 460: * 461: * @deprecated 462: */ 463: public synchronized void send(DatagramPacket packet, byte ttl) 464: throws IOException 465: { 466: if (isClosed()) 467: throw new SocketException("socket is closed"); 468: 469: SecurityManager s = System.getSecurityManager(); 470: if (s != null) 471: { 472: InetAddress addr = packet.getAddress(); 473: if (addr.isMulticastAddress()) 474: s.checkPermission(new SocketPermission(addr.getHostName() 475: + packet.getPort(), 476: "accept,connect")); 477: else 478: s.checkConnect(addr.getHostAddress(), packet.getPort()); 479: } 480: 481: int oldttl = getImpl().getTimeToLive(); 482: getImpl().setTimeToLive(((int) ttl) & 0xFF); 483: getImpl().send(packet); 484: getImpl().setTimeToLive(oldttl); 485: } 486: }
GNU Classpath (0.20) |