Multicasting with DatagramSocket
DatagramChannel
implements the MulticastChannel
interface and provides an alternative API for sending and receiving multicast datagrams. The MulticastChannel
API supports both any-source and source-specific multicast. Consider using DatagramChannel
for multicasting.
DatagramSocket
can be used directly for multicasting. However, contrarily to MulticastSocket
, DatagramSocket
doesn't call the setReuseAddress(boolean)
method to enable the SO_REUSEADDR socket option by default. If creating a DatagramSocket
intended to later join a multicast group, the caller should consider explicitly enabling the SO_REUSEADDR option.
An instance of DatagramSocket
can be used to send or receive multicast datagram packets. It is not necessary to join a multicast group in order to send multicast datagrams. Before sending out multicast datagram packets however, the default outgoing interface for sending multicast datagram should first be configured using setOption
and StandardSocketOptions.IP_MULTICAST_IF
:
DatagramSocket sender = new DatagramSocket(new InetSocketAddress(0));
NetworkInterface outgoingIf = NetworkInterface.getByName("en0");
sender.setOption(StandardSocketOptions.IP_MULTICAST_IF, outgoingIf);
// optionally configure multicast TTL; the TTL defines the scope of a
// multicast datagram, for example, confining it to host local (0) or
// link local (1) etc...
int ttl = ...; // a number between 0 and 255
sender.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
// send a packet to a multicast group
byte[] msgBytes = ...;
InetAddress mcastaddr = InetAddress.getByName("228.5.6.7");
int port = 6789;
InetSocketAddress dest = new InetSocketAddress(mcastaddr, port);
DatagramPacket hi = new DatagramPacket(msgBytes, msgBytes.length, dest);
sender.send(hi);
An instance of DatagramSocket
can also be used to receive multicast datagram packets. A DatagramSocket
that is created with the intent of receiving multicast datagrams should be created unbound. Before binding the socket, setReuseAddress(true)
should be configured:
DatagramSocket socket = new DatagramSocket(null); // unbound
socket.setReuseAddress(true); // set reuse address before binding
socket.bind(new InetSocketAddress(6789)); // bind
// joinGroup 228.5.6.7
InetAddress mcastaddr = InetAddress.getByName("228.5.6.7");
InetSocketAddress group = new InetSocketAddress(mcastaddr, 0);
NetworkInterface netIf = NetworkInterface.getByName("en0");
socket.joinGroup(group, netIf);
byte[] msgBytes = new byte[1024]; // up to 1024 bytes
DatagramPacket packet = new DatagramPacket(msgBytes, msgBytes.length);
socket.receive(packet);
....
// eventually leave group
socket.leaveGroup(group, netIf);
Platform dependencies
The multicast implementation is intended to map directly to the native multicasting facility. Consequently, the following items should be considered when developing an application that receives IP multicast datagrams:
- Contrarily to
DatagramChannel
, the constructors of DatagramSocket
do not allow to specify the ProtocolFamily
of the underlying socket. Consequently, the protocol family of the underlying socket may not correspond to the protocol family of the multicast groups that the DatagramSocket
will attempt to join.
There is no guarantee that a DatagramSocket
with an underlying socket created in one protocol family can join and receive multicast datagrams when the address of the multicast group corresponds to another protocol family. For example, it is implementation specific if a DatagramSocket
to an IPv6 socket can join an IPv4 multicast group and receive multicast datagrams sent to the group.
- Before joining a multicast group, the
DatagramSocket
should be bound to the wildcard address. If the socket is bound to a specific address, rather than the wildcard address then it is implementation specific if multicast datagrams are received by the socket.
- The SO_REUSEADDR option should be enabled prior to binding the socket. This is required to allow multiple members of the group to bind to the same address.
DatagramChannel
, or subclassDatagramSocket
directly.This method provided a way in early JDK releases to replace the system wide implementation of
DatagramSocket
. It has been mostly obsolete since Java 1.4. If required, aDatagramSocket
can be created to use a custom implementation by extendingDatagramSocket
and using the protected constructor that takes an implementation as a parameter.