Path: blob/master/src/java.base/share/classes/java/net/MulticastSocket.java
41152 views
/*1* Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.net;2627import java.io.IOException;28import java.nio.channels.DatagramChannel;29import java.nio.channels.MulticastChannel;3031/**32* A {@code MulticastSocket} is a datagram socket that is33* convenient for sending and receiving IP multicast datagrams.34* The {@code MulticastSocket} constructors create a socket35* with appropriate socket options enabled that make36* it suitable for receiving multicast datagrams.37* The {@code MulticastSocket} class additionally defines38* convenient setter and getter methods for socket options39* that are commonly used by multicasting applications.40* <P>41* Joining one or more multicast groups makes it possible to42* receive multicast datagrams sent to these groups.43* <P>44* An IPv4 multicast group is specified by a class D IP address45* and by a standard UDP port number. Class D IP addresses46* are in the range {@code 224.0.0.0} to {@code 239.255.255.255},47* inclusive. The address 224.0.0.0 is reserved and should not be used.48* <P>49* One would join a multicast group by first creating a MulticastSocket50* with the desired port, then invoking the51* <CODE>joinGroup</CODE> method, specifying the group address and52* the network interface through which multicast datagrams will be53* received:54* <PRE>{@code55* // join a Multicast group and send the group salutations56* ...57* String msg = "Hello";58* InetAddress mcastaddr = InetAddress.getByName("228.5.6.7");59* InetSocketAddress group = new InetSocketAddress(mcastaddr, 6789);60* NetworkInterface netIf = NetworkInterface.getByName("bge0");61* MulticastSocket s = new MulticastSocket(6789);62*63* s.joinGroup(new InetSocketAddress(mcastaddr, 0), netIf);64* byte[] msgBytes = msg.getBytes(StandardCharsets.UTF_8);65* DatagramPacket hi = new DatagramPacket(msgBytes, msgBytes.length, group);66* s.send(hi);67* // get their responses!68* byte[] buf = new byte[1000];69* DatagramPacket recv = new DatagramPacket(buf, buf.length);70* s.receive(recv);71* ...72* // OK, I'm done talking - leave the group...73* s.leaveGroup(group, netIf);74* }</PRE>75*76* When one sends a message to a multicast group, <B>all</B> subscribing77* recipients to that host and port receive the message (within the78* time-to-live range of the packet, see below). The socket needn't79* be a member of the multicast group to send messages to it.80* <P>81* When a socket subscribes to a multicast group/port, it receives82* datagrams sent by other hosts to the group/port, as do all other83* members of the group and port. A socket relinquishes membership84* in a group by the leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)85* method.86* <B>Multiple MulticastSockets</B> may subscribe to a multicast group87* and port concurrently, and they will all receive group datagrams.88*89* <p> The {@code DatagramSocket} and {@code MulticastSocket}90* classes define convenience methods to set and get several91* socket options. Like {@code DatagramSocket} this class also92* supports the {@link #setOption(SocketOption, Object) setOption}93* and {@link #getOption(SocketOption) getOption} methods to set94* and query socket options.95* <a id="MulticastOptions"></a>The set of supported socket options96* is defined in <a href="DatagramSocket.html#SocketOptions">{@code DatagramSocket}</a>.97* Additional (implementation specific) options may also be supported.98*99* @apiNote {@link DatagramSocket} may be used directly for100* sending and receiving multicast datagrams.101* {@link DatagramChannel} implements the {@link MulticastChannel} interface102* and provides an alternative API for sending and receiving multicast datagrams.103* The {@link MulticastChannel} API supports both {@linkplain104* MulticastChannel#join(InetAddress, NetworkInterface) any-source} and105* {@linkplain MulticastChannel#join(InetAddress, NetworkInterface, InetAddress)106* source-specific} multicast. Consider using {@link DatagramChannel} for107* multicasting.108*109* @author Pavani Diwanji110* @since 1.1111*/112public class MulticastSocket extends DatagramSocket {113114@Override115final MulticastSocket delegate() {116return (MulticastSocket) super.delegate();117}118119/**120* Create a MulticastSocket that delegates to the given delegate if not null.121* @param delegate the delegate, can be null.122*/123MulticastSocket(MulticastSocket delegate) {124super(delegate);125}126127128/**129* Constructs a multicast socket and binds it to any available port130* on the local host machine. The socket will be bound to the131* {@link InetAddress#isAnyLocalAddress wildcard} address.132*133* <p>134* If there is a security manager, its {@code checkListen} method is first135* called with 0 as its argument to ensure the operation is allowed. This136* could result in a SecurityException.137* <p>138* When the socket is created the139* {@link DatagramSocket#setReuseAddress(boolean)} method is called to140* enable the SO_REUSEADDR socket option.141*142* @throws IOException if an I/O exception occurs while creating the143* MulticastSocket144* @throws SecurityException if a security manager exists and its145* {@code checkListen} method doesn't allow the operation.146* @see SecurityManager#checkListen147* @see java.net.DatagramSocket#setReuseAddress(boolean)148* @see java.net.DatagramSocketImpl#setOption(SocketOption, Object)149*/150public MulticastSocket() throws IOException {151this(new InetSocketAddress(0));152}153154/**155* Constructs a multicast socket and binds it to the specified port156* on the local host machine. The socket will be bound to the157* {@link InetAddress#isAnyLocalAddress wildcard} address.158*159* <p>If there is a security manager,160* its {@code checkListen} method is first called161* with the {@code port} argument162* as its argument to ensure the operation is allowed.163* This could result in a SecurityException.164* <p>165* When the socket is created the166* {@link DatagramSocket#setReuseAddress(boolean)} method is167* called to enable the SO_REUSEADDR socket option.168*169* @param port port to use170* @throws IOException if an I/O exception occurs171* while creating the MulticastSocket172* @throws SecurityException if a security manager exists and its173* {@code checkListen} method doesn't allow the operation.174* @throws IllegalArgumentException if port is <a href="DatagramSocket.html#PortRange">175* out of range.</a>176*177* @see SecurityManager#checkListen178* @see java.net.DatagramSocket#setReuseAddress(boolean)179*/180public MulticastSocket(int port) throws IOException {181this(new InetSocketAddress(port));182}183184/**185* Creates a multicast socket, bound to the specified local186* socket address.187* <p>188* If the address is {@code null} an unbound socket will be created.189*190* <p>If there is a security manager,191* its {@code checkListen} method is first called192* with the SocketAddress port as its argument to ensure the operation is allowed.193* This could result in a SecurityException.194* <p>195* When the socket is created the196* {@link DatagramSocket#setReuseAddress(boolean)} method is197* called to enable the SO_REUSEADDR socket option.198*199* @param bindaddr Socket address to bind to, or {@code null} for200* an unbound socket.201* @throws IOException if an I/O exception occurs202* while creating the MulticastSocket203* @throws SecurityException if a security manager exists and its204* {@code checkListen} method doesn't allow the operation.205* @see SecurityManager#checkListen206* @see java.net.DatagramSocket#setReuseAddress(boolean)207*208* @since 1.4209*/210public MulticastSocket(SocketAddress bindaddr) throws IOException {211this(createDelegate(bindaddr, MulticastSocket.class));212}213214/**215* Set the default time-to-live for multicast packets sent out216* on this {@code MulticastSocket} in order to control the217* scope of the multicasts.218*219* <p>The ttl is an <b>unsigned</b> 8-bit quantity, and so <B>must</B> be220* in the range {@code 0 <= ttl <= 0xFF }.221*222* @param ttl the time-to-live223* @throws IOException if an I/O exception occurs224* while setting the default time-to-live value225* @deprecated use the {@link #setTimeToLive(int)} method instead, which uses226* <b>int</b> instead of <b>byte</b> as the type for ttl.227* @see #getTTL()228*/229@Deprecated230public void setTTL(byte ttl) throws IOException {231delegate().setTTL(ttl);232}233234/**235* Set the default time-to-live for multicast packets sent out236* on this {@code MulticastSocket} in order to control the237* scope of the multicasts.238*239* <P> The ttl <B>must</B> be in the range {@code 0 <= ttl <=240* 255} or an {@code IllegalArgumentException} will be thrown.241* Multicast packets sent with a TTL of {@code 0} are not transmitted242* on the network but may be delivered locally.243*244* @apiNote245* This method is equivalent to calling {@link #setOption(SocketOption, Object)246* setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl)}.247*248* @param ttl249* the time-to-live250*251* @throws IOException252* if an I/O exception occurs while setting the253* default time-to-live value254*255* @see #getTimeToLive()256* @see StandardSocketOptions#IP_MULTICAST_TTL257* @since 1.2258*/259public void setTimeToLive(int ttl) throws IOException {260delegate().setTimeToLive(ttl);261}262263/**264* Get the default time-to-live for multicast packets sent out on265* the socket.266*267* @throws IOException if an I/O exception occurs268* while getting the default time-to-live value269* @return the default time-to-live value270* @deprecated use the {@link #getTimeToLive()} method instead,271* which returns an <b>int</b> instead of a <b>byte</b>.272* @see #setTTL(byte)273*/274@Deprecated275public byte getTTL() throws IOException {276return delegate().getTTL();277}278279/**280* Get the default time-to-live for multicast packets sent out on281* the socket.282*283* @apiNote284* This method is equivalent to calling {@link #getOption(SocketOption)285* getOption(StandardSocketOptions.IP_MULTICAST_TTL)}.286*287* @throws IOException if an I/O exception occurs while288* getting the default time-to-live value289* @return the default time-to-live value290* @see #setTimeToLive(int)291* @see StandardSocketOptions#IP_MULTICAST_TTL292* @since 1.2293*/294public int getTimeToLive() throws IOException {295return delegate().getTimeToLive();296}297298/**299* Joins a multicast group. Its behavior may be affected by300* {@code setInterface} or {@code setNetworkInterface}.301*302* <p>If there is a security manager, this method first303* calls its {@code checkMulticast} method with the304* {@code mcastaddr} argument as its argument.305*306* @apiNote307* Calling this method is equivalent to calling308* {@link #joinGroup(SocketAddress, NetworkInterface)309* joinGroup(new InetSocketAddress(mcastaddr, 0), null)}.310*311* @param mcastaddr is the multicast address to join312* @throws IOException if there is an error joining,313* or when the address is not a multicast address,314* or the platform does not support multicasting315* @throws SecurityException if a security manager exists and its316* {@code checkMulticast} method doesn't allow the join.317* @deprecated This method does not accept the network interface on318* which to join the multicast group. Use319* {@link #joinGroup(SocketAddress, NetworkInterface)} instead.320* @see SecurityManager#checkMulticast(InetAddress)321*/322@Deprecated(since="14")323public void joinGroup(InetAddress mcastaddr) throws IOException {324delegate().joinGroup(mcastaddr);325}326327/**328* Leave a multicast group. Its behavior may be affected by329* {@code setInterface} or {@code setNetworkInterface}.330*331* <p>If there is a security manager, this method first332* calls its {@code checkMulticast} method with the333* {@code mcastaddr} argument as its argument.334*335* @apiNote336* Calling this method is equivalent to calling337* {@link #leaveGroup(SocketAddress, NetworkInterface)338* leaveGroup(new InetSocketAddress(mcastaddr, 0), null)}.339*340* @param mcastaddr is the multicast address to leave341* @throws IOException if there is an error leaving342* or when the address is not a multicast address.343* @throws SecurityException if a security manager exists and its344* {@code checkMulticast} method doesn't allow the operation.345* @deprecated This method does not accept the network interface on which346* to leave the multicast group. Use347* {@link #leaveGroup(SocketAddress, NetworkInterface)} instead.348* @see SecurityManager#checkMulticast(InetAddress)349*/350@Deprecated(since="14")351public void leaveGroup(InetAddress mcastaddr) throws IOException {352delegate().leaveGroup(mcastaddr);353}354355/**356* {@inheritDoc}357* @throws IOException {@inheritDoc}358* @throws SecurityException {@inheritDoc}359* @throws IllegalArgumentException {@inheritDoc}360* @see SecurityManager#checkMulticast(InetAddress)361* @see DatagramChannel#join(InetAddress, NetworkInterface)362* @see StandardSocketOptions#IP_MULTICAST_IF363* @see #setNetworkInterface(NetworkInterface)364* @see #setInterface(InetAddress)365* @since 1.4366*/367@Override368public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)369throws IOException {370super.joinGroup(mcastaddr, netIf);371}372373/**374* {@inheritDoc}375* @apiNote {@inheritDoc}376* @throws IOException {@inheritDoc}377* @throws SecurityException {@inheritDoc}378* @throws IllegalArgumentException {@inheritDoc}379* @see SecurityManager#checkMulticast(InetAddress)380* @see #joinGroup(SocketAddress, NetworkInterface)381* @since 1.4382*/383@Override384public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)385throws IOException {386super.leaveGroup(mcastaddr, netIf);387}388389/**390* Set the multicast network interface used by methods391* whose behavior would be affected by the value of the392* network interface. Useful for multihomed hosts.393*394* @param inf the InetAddress395* @throws SocketException if there is an error in396* the underlying protocol, such as a TCP error.397* @deprecated The InetAddress may not uniquely identify398* the network interface. Use399* {@link #setNetworkInterface(NetworkInterface)} instead.400* @see #getInterface()401*/402@Deprecated(since="14")403public void setInterface(InetAddress inf) throws SocketException {404delegate().setInterface(inf);405}406407/**408* Retrieve the address of the network interface used for409* multicast packets.410*411* @return An {@code InetAddress} representing the address412* of the network interface used for multicast packets,413* or if no interface has been set, an {@code InetAddress}414* representing any local address.415* @throws SocketException if there is an error in the416* underlying protocol, such as a TCP error.417* @deprecated The network interface may not be uniquely identified by418* the InetAddress returned.419* Use {@link #getNetworkInterface()} instead.420* @see #setInterface(java.net.InetAddress)421*/422@Deprecated(since="14")423public InetAddress getInterface() throws SocketException {424return delegate().getInterface();425}426427/**428* Specify the network interface for outgoing multicast datagrams429* sent on this socket.430*431* @apiNote432* This method is equivalent to calling {@link #setOption(SocketOption, Object)433* setOption(StandardSocketOptions.IP_MULTICAST_IF, netIf)}.434*435* @param netIf the interface436* @throws SocketException if there is an error in437* the underlying protocol, such as a TCP error.438* @see #getNetworkInterface()439* @see StandardSocketOptions#IP_MULTICAST_IF440* @since 1.4441*/442public void setNetworkInterface(NetworkInterface netIf)443throws SocketException {444delegate().setNetworkInterface(netIf);445}446447/**448* Get the multicast network interface set for outgoing multicast449* datagrams sent from this socket.450*451* @apiNote452* When an interface is set, this method is equivalent453* to calling {@link #getOption(SocketOption)454* getOption(StandardSocketOptions.IP_MULTICAST_IF)}.455*456* @throws SocketException if there is an error in457* the underlying protocol, such as a TCP error.458* @return The multicast {@code NetworkInterface} currently set. A placeholder459* NetworkInterface is returned when there is no interface set; it has460* a single InetAddress to represent any local address.461* @see #setNetworkInterface(NetworkInterface)462* @see StandardSocketOptions#IP_MULTICAST_IF463* @since 1.4464*/465public NetworkInterface getNetworkInterface() throws SocketException {466return delegate().getNetworkInterface();467}468469/**470* Disable/Enable local loopback of multicast datagrams.471* The option is used by the platform's networking code as a hint472* for setting whether multicast data will be looped back to473* the local socket.474*475* <p>Because this option is a hint, applications that want to476* verify what loopback mode is set to should call477* {@link #getLoopbackMode()}478* @param disable {@code true} to disable the LoopbackMode479* @throws SocketException if an error occurs while setting the value480* @since 1.4481* @deprecated Use {@link #setOption(SocketOption, Object)} with482* {@link java.net.StandardSocketOptions#IP_MULTICAST_LOOP}483* instead. The loopback mode is enabled by default,484* {@code MulticastSocket.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, false)}485* disables it.486* @see #getLoopbackMode487*/488@Deprecated(since="14")489public void setLoopbackMode(boolean disable) throws SocketException {490delegate().setLoopbackMode(disable);491}492493/**494* Get the setting for local loopback of multicast datagrams.495*496* @throws SocketException if an error occurs while getting the value497* @return true if the LoopbackMode has been disabled498* @since 1.4499* @deprecated Use {@link #getOption(SocketOption)} with500* {@link java.net.StandardSocketOptions#IP_MULTICAST_LOOP}501* instead.502* @see #setLoopbackMode503*/504@Deprecated(since="14")505public boolean getLoopbackMode() throws SocketException {506return delegate().getLoopbackMode();507}508509/**510* Sends a datagram packet to the destination, with a TTL (time-to-live)511* other than the default for the socket. This method512* need only be used in instances where a particular TTL is desired;513* otherwise it is preferable to set a TTL once on the socket, and514* use that default TTL for all packets. This method does <B>not515* </B> alter the default TTL for the socket. Its behavior may be516* affected by {@code setInterface}.517*518* <p>If there is a security manager, this method first performs some519* security checks. First, if {@code p.getAddress().isMulticastAddress()}520* is true, this method calls the521* security manager's {@code checkMulticast} method522* with {@code p.getAddress()} and {@code ttl} as its arguments.523* If the evaluation of that expression is false,524* this method instead calls the security manager's525* {@code checkConnect} method with arguments526* {@code p.getAddress().getHostAddress()} and527* {@code p.getPort()}. Each call to a security manager method528* could result in a SecurityException if the operation is not allowed.529*530* @param p is the packet to be sent. The packet should contain531* the destination multicast ip address and the data to be sent.532* One does not need to be the member of the group to send533* packets to a destination multicast address.534* @param ttl optional time to live for multicast packet.535* default ttl is 1.536*537* @throws IOException is raised if an error occurs i.e538* error while setting ttl.539* @throws SecurityException if a security manager exists and its540* {@code checkMulticast} or {@code checkConnect}541* method doesn't allow the send.542* @throws PortUnreachableException may be thrown if the socket is connected543* to a currently unreachable destination. Note, there is no544* guarantee that the exception will be thrown.545* @throws IllegalArgumentException if the socket is connected,546* and connected address and packet address differ, or547* if the socket is not connected and the packet address548* is not set or if its port is out of range.549*550*551* @deprecated Use the following code or its equivalent instead:552* <pre>{@code ......553* int ttl = mcastSocket.getOption(StandardSocketOptions.IP_MULTICAST_TTL);554* mcastSocket.setOption(StandardSocketOptions.IP_MULTICAST_TTL, newttl);555* mcastSocket.send(p);556* mcastSocket.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);557* ......}</pre>558*559* @see DatagramSocket#send560* @see DatagramSocket#receive561* @see SecurityManager#checkMulticast(java.net.InetAddress, byte)562* @see SecurityManager#checkConnect563*/564@Deprecated565public void send(DatagramPacket p, byte ttl)566throws IOException {567delegate().send(p, ttl);568}569}570571572