1

I want to multicast data to the all the network cards present in the system using boost asio(udp). Can anyone help me in understanding how this can be done.I have created following example but its not working.The stream data send to each socket is getting mixed and the output is a mix of all sockets data on a single interface.

//e.g Assume data send to Interface1 is "Abcd"(Note: each interface has a separate socket)

data send to Interface2 is "xyz"

Then the output is only received from Interface1 ,the out stream is mixed(e.g "abxycdz" or "abxcdzy" etc)

Please help me in understanding the issue.

for(int i=0;i<NoOfInterfcaes;i++)
{
   Open("229.1.1.1",1000,sNetInterfcaeAddList[i],false);

}

....................................


for(int i=0;i<NoOfInterfcaes;i++)
{
   send(dataBuffer,len);

}

....................................

void Open(std::string &multicastIp,int nPort, std::string& sNetInterfcaeIpAdd,bool broadcast)
{

   m_sNetInterfcaeIpAdd=sNetInterfcaeIpAdd;
   m_sMulticastIp=multicastIp;
   m_nport = nPort;
   m_broadcast = broadcast ;
   // try and open socket
   const ip::udp::resolver::query queryIF( ip::udp::v4(),multicastIp.c_str(), nPort ); 
   ///resolve the connection
   m_resolver.async_resolve(queryIF,
                            boost::bind(&handle_resolve, this,
                                         boost::asio::placeholders::error,
                                         boost::asio::placeholders::iterator));

}
void handle_resolve(const boost::system::error_code& err,
                                       boost::asio::ip::udp::resolver::iterator endpoint_iterator)
{
   if (!err)
   {
      //make a connection
      m_socket.async_connect(*endpoint_iterator,
                              boost::bind(&handle_connect, this,
                                          boost::asio::placeholders::error, endpoint_iterator));
   }
   else
   {
      //error message
   }
}
void handle_connect(const boost::system::error_code& error,
                                       boost::asio::ip::udp::resolver::iterator endpoint_iterator)
{
   if (!error)
   {

      //Select the network adaptor
      m_socket.set_option( boost::asio::ip::multicast::outbound_interface( boost::asio::ip::address_v4::from_string(m_sNetInterfcaeIpAdd)));
      m_socket.set_option( boost::asio::ip::multicast::enable_loopback(false));
      if(m_broadcast)
      {
         boost::asio::socket_base::broadcast option(true);
         m_socket.set_option(option);
      }
   }
   else if (endpoint_iterator != boost::asio::ip::udp::resolver::iterator())
   {
      // The connection failed. Try the next endpoint in the list.
      m_socket.close();
      //try to connect
      m_socket.async_connect(*endpoint_iterator,
                              boost::bind(&handle_connect, this,
                                          boost::asio::placeholders::error, endpoint_iterator));
   }
   else
   {
      //
   }
}
Ven
  • 247
  • 1
  • 5
  • 18
  • I have fixed this issue.I think we have to use separate multicast addresses for each network adapter and need to call m_socket.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::addr‌​ess_v4::from_string(m_sMulticastIp), boost::asio::ip::address_v4::from_string(m_sNetInterfcaeIpAdd))); after m_socket.set_option( boost::asio::ip::multicast::outbound_interface( boost::asio::ip::address_v4::from_string(m_sNetInterfcaeIpAdd))); – Ven Feb 20 '13 at 11:02

1 Answers1

1

You use this one socket per adapter, binding each to its adapter using the code from this question: Boost asio socket multicast to a specific ethernet interface

Community
  • 1
  • 1
eile
  • 1,153
  • 6
  • 18
  • Thank You Eile but the problem is how do I get the interface address. – Ven Feb 07 '13 at 10:59
  • I don't think it's possible with boost::asio, but implementations for the most important OS's can be found in hwsd: https://github.com/Eyescale/hwsd/blob/master/hwsd/net/sys/module.cpp – eile Feb 08 '13 at 17:05
  • @Ven: It is not possible with Boost.Asio, but other libraries, such as [libuv](https://github.com/joyent/libuv) can be used to query a system for its network interfaces. [Here](http://nikhilm.github.com/uvbook/networking.html#network-interfaces) is an example from the libuv introduction. – Tanner Sansbury Feb 08 '13 at 19:20
  • Thank you Eile,Twsansbury. It make sense. – Ven Feb 11 '13 at 09:50
  • Hi Eile, I have checked the answer you have given in the above link. – Ven Feb 18 '13 at 15:24
  • Hi eile, I have checked the answer you have given in the above link .I have to multicast a stream to two interfaces ("192.168.xx.yy","192.168.xx.zz" on the multicast address 229.1.1.1 ,port 1000.So i have opened two sockets using the same multicast address,once the connection is made I am calling option to bound to specific interface as shown above but the problem is that data of the both streams is sent to only one interface – Ven Feb 18 '13 at 15:40
  • Hi Eile,I have fixed this issue.I think we have to use separate multicast addresses for each network adapter and need to call m_socket.set_option(boost::asio::ip::multicast::join_group(boost::asio::ip::addr‌​‌​ess_v4::from_string(m_sMulticastIp), boost::asio::ip::address_v4::from_string(m_sNetInterfcaeIpAdd))); after m_socket.set_option( boost::asio::ip::multicast::outbound_interface( boost::asio::ip::address_v4::from_string(m_sNetInterfcaeIpAdd))); – Ven Feb 20 '13 at 11:06