13

I tried the example, but it does not work. Apparently it does not set IPPROTO_IP/IP_MULTICAST_IF option. I can only find boost::asio::ip::multicast::outbound_interface for IPPROTO_IP/IP_MULTICAST_IF, I tried but failed. Is there any way to make boost::asio::ip::multicast work without calling c-level setsockopt?

boost::asio::ip::udp::endpoint listen_endpoint(
    listen_address, multicast_port);
socket_.open(listen_endpoint.protocol());
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
socket_.bind(listen_endpoint);

// Join the multicast group.
socket_.set_option(
    boost::asio::ip::multicast::join_group(multicast_address));
poordeveloper
  • 2,272
  • 1
  • 23
  • 36
  • 2
    use `multicast::join_group(multicast_address, listen_endpoint.address().to_v4())`. – Stefan Näwe Dec 30 '11 at 14:04
  • 1
    Thanks for your reminder. Just tried, and we must set "0.0.0.0" to listen_endpoint. So the working version is boost::asio::ip::udp::endpoint listen_endpoint(udp::v4(), multicast_port); ... socket_.set_option(multicast::join_group(address::from_string(group_).to_v4(), address::from_string(interface).to_v4())); – poordeveloper Dec 30 '11 at 16:21
  • @Stefan post your comment as an answer – Sam Miller Dec 30 '11 at 18:28
  • 1
    I had this problem, but answers didn't helped me (even if they're interesting). Instead, the following question helped me: [What does it mean to bind a multicast (udp) socket?](http://stackoverflow.com/questions/10692956/what-does-it-mean-to-bind-a-multicast-udp-socket) (added here for potential future readers). – Synxis Mar 11 '14 at 13:44

2 Answers2

9

Correct Answer:

boost::asio::ip::udp::endpoint listen_endpoint(udp::v4(), multicast_port); 
...
socket_.set_option(multicast::join_group(
  address::from_string(multicast_address).to_v4(), 
  address::from_string(interface).to_v4()));
poordeveloper
  • 2,272
  • 1
  • 23
  • 36
8

I think there's an error in boost example code for udp multicast.

In the example code they bind socket to local interface but for udp multicast you have to bind to the udp multicast group IP and port.

socket_.bind(listen_endpoint);

should be:

socket_.bind(
    boost::asio::ip::udp::endpoint( multicast_address, multicast_port ) );

see multicast howto:

... for a process to receive multicast datagrams it has to ask the kernel to join the group and bind the port those datagrams were being sent to. The UDP layer uses both the destination address and port to demultiplex the packets and decide which socket(s) deliver them to ...

... it is necessary to advise the kernel which multicast groups we are interested in. That is, we have to ask the kernel to "join" those multicast groups ...

check if you joined the group on correct interface with netstat -g | grep <multicast_group_ip>

this is I believe incorrect boost example code:

boost::asio::ip::udp::endpoint listen_endpoint(
    listen_address, multicast_port);
socket_.open(listen_endpoint.protocol());
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
socket_.bind(listen_endpoint);

// Join the multicast group.
socket_.set_option(
    boost::asio::ip::multicast::join_group(multicast_address));

socket_.async_receive_from(
    boost::asio::buffer(data_, max_length), sender_endpoint_,
    boost::bind(&receiver::handle_receive_from, this,
      boost::asio::placeholders::error,
      boost::asio::placeholders::bytes_transferred));
stefanB
  • 77,323
  • 27
  • 116
  • 141
  • In my testing, that's what it takes to get it working under Linux, but @poordeveloper's answer works under MS Windows. Not sure why. – ulatekh Mar 25 '22 at 21:06