MulticastSocket.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /* MulticastSocket.java -- Class for using multicast sockets
  2. Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
  3. Free Software Foundation, Inc.
  4. This file is part of GNU Classpath.
  5. GNU Classpath is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9. GNU Classpath is distributed in the hope that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GNU Classpath; see the file COPYING. If not, write to the
  15. Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  16. 02111-1307 USA.
  17. Linking this library statically or dynamically with other modules is
  18. making a combined work based on this library. Thus, the terms and
  19. conditions of the GNU General Public License cover the whole
  20. combination.
  21. As a special exception, the copyright holders of this library give you
  22. permission to link this library with independent modules to produce an
  23. executable, regardless of the license terms of these independent
  24. modules, and to copy and distribute the resulting executable under
  25. terms of your choice, provided that you also meet, for each linked
  26. independent module, the terms and conditions of the license of that
  27. module. An independent module is a module which is not derived from
  28. or based on this library. If you modify this library, you may extend
  29. this exception to your version of the library, but you are not
  30. obligated to do so. If you do not wish to do so, delete this
  31. exception statement from your version. */
  32. package java.net;
  33. import java.io.IOException;
  34. import java.util.Enumeration;
  35. /**
  36. * Written using on-line Java Platform 1.2 API Specification, as well
  37. * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
  38. * Status: Believed complete and correct.
  39. */
  40. /**
  41. * This class models a multicast UDP socket. A multicast address is a
  42. * class D internet address (one whose most significant bits are 1110).
  43. * A multicast group consists of a multicast address and a well known
  44. * port number. All members of the group listening on that address and
  45. * port will receive all the broadcasts to the group.
  46. * <p>
  47. * Please note that applets are not allowed to use multicast sockets
  48. *
  49. * Written using on-line Java Platform 1.2 API Specification, as well
  50. * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
  51. * Status: Believed complete and correct.
  52. *
  53. * @author Warren Levy <warrenl@cygnus.com>
  54. * @author Aaron M. Renn (arenn@urbanophile.com) (Documentation comments)
  55. * @since 1.1
  56. * @date May 18, 1999.
  57. */
  58. public class MulticastSocket extends DatagramSocket
  59. {
  60. // FIXME: the local addr bound to the multicast socket can be reused;
  61. // unlike unicast sockets. It binds to any available network interface.
  62. // See p.1159 JCL book.
  63. /**
  64. * Create a MulticastSocket that this not bound to any address
  65. *
  66. * @exception IOException If an error occurs
  67. * @exception SecurityException If a security manager exists and its
  68. * checkListen method doesn't allow the operation
  69. */
  70. public MulticastSocket() throws IOException
  71. {
  72. super(0, null);
  73. }
  74. /**
  75. * Create a multicast socket bound to the specified port
  76. *
  77. * @param port The port to bind to
  78. *
  79. * @exception IOException If an error occurs
  80. * @exception SecurityException If a security manager exists and its
  81. * checkListen method doesn't allow the operation
  82. */
  83. public MulticastSocket(int port) throws IOException
  84. {
  85. super(port, null);
  86. }
  87. /**
  88. * Create a multicast socket bound to the specified SocketAddress.
  89. *
  90. * @param address The SocketAddress the multicast socket will be bound to
  91. *
  92. * @exception IOException If an error occurs
  93. * @exception SecurityException If a security manager exists and its
  94. * checkListen method doesn't allow the operation
  95. *
  96. * @since 1.4
  97. */
  98. public MulticastSocket(SocketAddress address) throws IOException
  99. {
  100. super(address);
  101. }
  102. /**
  103. * Returns the interface being used for multicast packets
  104. *
  105. * @return The multicast interface
  106. *
  107. * @exception SocketException If an error occurs
  108. */
  109. public InetAddress getInterface() throws SocketException
  110. {
  111. return (InetAddress) impl.getOption(SocketOptions.IP_MULTICAST_IF);
  112. }
  113. /**
  114. * Returns the current value of the "Time to Live" option. This is the
  115. * number of hops a packet can make before it "expires". This method id
  116. * deprecated. Use <code>getTimeToLive</code> instead.
  117. *
  118. * @return The TTL value
  119. *
  120. * @exception IOException If an error occurs
  121. *
  122. * @deprecated 1.2 Replaced by getTimeToLive()
  123. *
  124. * @see Multicastsocket:getTimeToLive
  125. */
  126. public byte getTTL() throws IOException
  127. {
  128. // Use getTTL here rather than getTimeToLive in case we're using an impl
  129. // other than the default PlainDatagramSocketImpl and it doesn't have
  130. // getTimeToLive yet.
  131. return impl.getTTL();
  132. }
  133. /**
  134. * Returns the current value of the "Time to Live" option. This is the
  135. * number of hops a packet can make before it "expires".
  136. *
  137. * @return The TTL value
  138. *
  139. * @exception IOException If an error occurs
  140. *
  141. * @since 1.2
  142. */
  143. public int getTimeToLive() throws IOException
  144. {
  145. return impl.getTimeToLive();
  146. }
  147. /**
  148. * Sets the interface to use for sending multicast packets.
  149. *
  150. * @param addr The new interface to use.
  151. *
  152. * @exception SocketException If an error occurs.
  153. *
  154. * @since 1.4
  155. */
  156. public void setInterface(InetAddress addr) throws SocketException
  157. {
  158. impl.setOption(SocketOptions.IP_MULTICAST_IF, addr);
  159. }
  160. /**
  161. * Sets the local network interface used to send multicast messages
  162. *
  163. * @param netIF The local network interface used to send multicast messages
  164. *
  165. * @exception SocketException If an error occurs
  166. *
  167. * @see MulticastSocket:getNetworkInterface
  168. *
  169. * @since 1.4
  170. */
  171. public void setNetworkInterface(NetworkInterface netIf)
  172. throws SocketException
  173. {
  174. if (impl == null)
  175. throw new SocketException (
  176. "MulticastSocket: Cant access socket implementation");
  177. Enumeration e = netIf.getInetAddresses ();
  178. if (!e.hasMoreElements ())
  179. throw new SocketException ("MulticastSocket: Error");
  180. InetAddress address = (InetAddress) e.nextElement ();
  181. impl.setOption (SocketOptions.IP_MULTICAST_IF, address);
  182. }
  183. /**
  184. * Gets the local network interface which is used to send multicast messages
  185. *
  186. * @return The local network interface to send multicast messages
  187. *
  188. * @exception SocketException If an error occurs
  189. *
  190. * @see MulticastSocket:setNetworkInterface
  191. *
  192. * @since 1.4
  193. */
  194. public NetworkInterface getNetworkInterface()
  195. throws SocketException
  196. {
  197. if (impl == null)
  198. throw new SocketException (
  199. "MulticastSocket: Cant access socket implementation");
  200. InetAddress address =
  201. (InetAddress) impl.getOption (SocketOptions.IP_MULTICAST_IF);
  202. NetworkInterface netIf = NetworkInterface.getByInetAddress (address);
  203. return netIf;
  204. }
  205. /**
  206. * Disable/Enable local loopback of multicast packets. The option is used by
  207. * the platform's networking code as a hint for setting whether multicast
  208. * data will be looped back to the local socket.
  209. *
  210. * Because this option is a hint, applications that want to verify what
  211. * loopback mode is set to should call #getLoopbackMode
  212. *
  213. * @param disable True to disable loopback mode
  214. *
  215. * @exception SocketException If an error occurs
  216. *
  217. * @since 1.4
  218. */
  219. public void setLoopbackMode(boolean disable) throws SocketException
  220. {
  221. if (impl == null)
  222. throw new SocketException (
  223. "MulticastSocket: Cant access socket implementation");
  224. impl.setOption (SocketOptions.IP_MULTICAST_LOOP, new Boolean (disable));
  225. }
  226. /**
  227. * Checks if local loopback mode is enabled or not
  228. *
  229. * @exception SocketException If an error occurs
  230. *
  231. * @since 1.4
  232. */
  233. public boolean getLoopbackMode() throws SocketException
  234. {
  235. Object obj = impl.getOption (SocketOptions.IP_MULTICAST_LOOP);
  236. if (obj instanceof Boolean)
  237. return ((Boolean) obj).booleanValue ();
  238. else
  239. throw new SocketException ("Unexpected type");
  240. }
  241. /**
  242. * Sets the "Time to Live" value for a socket. The value must be between
  243. * 1 and 255.
  244. *
  245. * @param ttl The new TTL value
  246. *
  247. * @exception IOException If an error occurs
  248. *
  249. * @deprecated 1.2 Replaced by <code>setTimeToLive</code>
  250. *
  251. * @see MulticastSocket:setTimeToLive
  252. */
  253. public void setTTL(byte ttl) throws IOException
  254. {
  255. // Use setTTL here rather than setTimeToLive in case we're using an impl
  256. // other than the default PlainDatagramSocketImpl and it doesn't have
  257. // setTimeToLive yet.
  258. impl.setTTL(ttl);
  259. }
  260. /**
  261. * Sets the "Time to Live" value for a socket. The value must be between
  262. * 1 and 255.
  263. *
  264. * @param ttl The new TTL value
  265. *
  266. * @exception IOException If an error occurs
  267. *
  268. * @since 1.2
  269. */
  270. public void setTimeToLive(int ttl) throws IOException
  271. {
  272. if (ttl <= 0 || ttl > 255)
  273. throw new IllegalArgumentException("Invalid ttl: " + ttl);
  274. impl.setTimeToLive(ttl);
  275. }
  276. /**
  277. * Joins the specified mulitcast group.
  278. *
  279. * @param addr The address of the group to join
  280. *
  281. * @exception IOException If an error occurs
  282. * @exception SecurityException If a security manager exists and its
  283. * checkMulticast method doesn't allow the operation
  284. */
  285. public void joinGroup(InetAddress mcastaddr) throws IOException
  286. {
  287. if (! mcastaddr.isMulticastAddress())
  288. throw new IOException("Not a Multicast address");
  289. SecurityManager s = System.getSecurityManager();
  290. if (s != null)
  291. s.checkMulticast(mcastaddr);
  292. impl.join(mcastaddr);
  293. }
  294. /**
  295. * Leaves the specified multicast group
  296. *
  297. * @param addr The address of the group to leave
  298. *
  299. * @exception IOException If an error occurs
  300. * @exception SecurityException If a security manager exists and its
  301. * checkMulticast method doesn't allow the operation
  302. */
  303. public void leaveGroup(InetAddress mcastaddr) throws IOException
  304. {
  305. if (! mcastaddr.isMulticastAddress())
  306. throw new IOException("Not a Multicast address");
  307. SecurityManager s = System.getSecurityManager();
  308. if (s != null)
  309. s.checkMulticast(mcastaddr);
  310. impl.leave(mcastaddr);
  311. }
  312. /**
  313. * Joins the specified mulitcast group on a specified interface.
  314. *
  315. * @param mcastaddr The multicast address to join
  316. * @param netIf The local network interface to receive the multicast
  317. * messages on or null to defer the interface set by #setInterface or
  318. * #setNetworkInterface
  319. *
  320. * @exception IOException If an error occurs
  321. * @exception IllegalArgumentException If address type is not supported
  322. * @exception SecurityException If a security manager exists and its
  323. * checkMulticast method doesn't allow the operation
  324. *
  325. * @see MulticastSocket:setInterface
  326. * @see MulticastSocket:setNetworkInterface
  327. *
  328. * @since 1.4
  329. */
  330. public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
  331. throws IOException
  332. {
  333. if (! (mcastaddr instanceof InetSocketAddress))
  334. throw new IllegalArgumentException ("SocketAddress type not supported");
  335. InetSocketAddress tmp = (InetSocketAddress) mcastaddr;
  336. if (! tmp.getAddress ().isMulticastAddress ())
  337. throw new IOException ("Not a Multicast address");
  338. SecurityManager s = System.getSecurityManager ();
  339. if (s != null)
  340. s.checkMulticast (tmp.getAddress ());
  341. impl.joinGroup (mcastaddr, netIf);
  342. }
  343. /**
  344. * Leaves the specified mulitcast group on a specified interface.
  345. *
  346. * @param mcastaddr The multicast address to leave
  347. * @param netIf The local networki interface or null to defer to the
  348. * interface set by setInterface or setNetworkInterface
  349. *
  350. * @exception IOException If an error occurs
  351. * @exception IllegalArgumentException If address type is not supported
  352. * @exception SecurityException If a security manager exists and its
  353. * checkMulticast method doesn't allow the operation
  354. *
  355. * @see MulticastSocket:setInterface
  356. * @see MulticastSocket:setNetworkInterface
  357. *
  358. * @since 1.4
  359. */
  360. public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
  361. throws IOException
  362. {
  363. InetSocketAddress tmp = (InetSocketAddress) mcastaddr;
  364. if (! tmp.getAddress ().isMulticastAddress ())
  365. throw new IOException ("Not a Multicast address");
  366. SecurityManager s = System.getSecurityManager ();
  367. if (s != null)
  368. s.checkMulticast (tmp.getAddress ());
  369. impl.leaveGroup (mcastaddr, netIf);
  370. }
  371. /**
  372. * Sends a packet of data to a multicast address with a TTL that is
  373. * different from the default TTL on this socket. The default TTL for
  374. * the socket is not changed.
  375. *
  376. * @param packet The packet of data to send
  377. * @param ttl The TTL for this packet
  378. *
  379. * @exception IOException If an error occurs
  380. * @exception SecurityException If a security manager exists and its
  381. * checkConnect or checkMulticast method doesn't allow the operation
  382. */
  383. public synchronized void send(DatagramPacket p, byte ttl) throws IOException
  384. {
  385. SecurityManager s = System.getSecurityManager();
  386. if (s != null)
  387. {
  388. InetAddress addr = p.getAddress();
  389. if (addr.isMulticastAddress())
  390. s.checkMulticast(addr, ttl);
  391. else
  392. s.checkConnect(addr.getHostAddress(), p.getPort());
  393. }
  394. int oldttl = impl.getTimeToLive();
  395. impl.setTimeToLive(((int) ttl) & 0xFF);
  396. impl.send(p);
  397. impl.setTimeToLive(oldttl);
  398. }
  399. } // class MulticastSocket