Multicast receiver with boost c++ not seeing data

Viewed 546

I am trying to use the example of Multicast receiver to listen to the application that sends UDP Multicast data over the network.

  • The listening IP is 193.x.x.107
  • The sender IP is 193.x.x.109
  • Multicast address is 231.11.1.5:6005

Here is a Wireshark capture of the data, to make sure that data are passing by:

Proof of Traffic

Here is the code from boost library:

 //
 // receiver.cpp
 // ~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //

 #include <iostream>
 #include <string>
 #include <boost/asio.hpp>
 #include "boost/bind.hpp"

 const short multicast_port = 6005;

 class receiver
 {
      public:
        receiver(boost::asio::io_service& io_service,
        const boost::asio::ip::address& listen_address,
        const boost::asio::ip::address& multicast_address)
        : socket_(io_service)
 {
     // Create the socket so that multiple may be bound to the same           address.
     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);

     std::cout << "Socket Created : " << std::endl;

     // 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));

    std::cout << "Mutilcast Group Joined : " << std::endl;
}

void handle_receive_from(const boost::system::error_code& error,
  size_t bytes_recvd)
{
     if (!error)
     {
         std::cout.write(data_, bytes_recvd);
         std::cout << std::endl;

         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));
    }
}

 private:
    boost::asio::ip::udp::socket socket_;
    boost::asio::ip::udp::endpoint sender_endpoint_;
    enum { max_length = 1024 };
    char data_[max_length];
 };

int main(int argc, char* argv[])
{
   try
   {
      if (argc != 3)
      {
          std::cerr << "Usage: receiver <listen_address> <multicast_address>\n";
          std::cerr << "  For IPv4, try:\n";
          std::cerr << "    receiver 0.0.0.0 239.255.0.1\n";
          std::cerr << "  For IPv6, try:\n";
          std::cerr << "    receiver 0::0 ff31::8000:1234\n";
          return 1;
      }

      boost::asio::io_service io_service;
      receiver r(io_service,
              boost::asio::ip::address::from_string(argv[1]),
              boost::asio::ip::address::from_string(argv[2]));

     std::cout << "Starting listening... " <<  std::endl;
     io_service.run();
  }
  catch (std::exception& e)
  {
      std::cerr << "Exception: " << e.what() << "\n";
}

return 0;
}

The problem is that the data pass by without being seen by the socket although Wireshark can see them.

I tried to run the socket as root without much more success.

Would anyone knows were this code is wrong?

1 Answers

thanks for trying to help me. Indeed the example from the website works fine.

I am trying to capture traffic send by another application (look at the wireshark screen capture). Note that 193.x.x.109 does not run the sender.cpp but is sending other data. Look at the little diagram below:

193.x.x.109 ------------------------------Multicast data -------------> 231.11.1.5:6005
                                                 |
193.x.x.107 -(Running receiver.cpp)--------------|

These data are binary (not string) if that's important.

The equivalent of tcpdump command would be:

tcpdump -i bond1 dst port 6005
Related