boost :: asio :: ip :: multicast :: join_group不起作用

poo*_*per 9 c++ boost-asio

我试过这个 例子,但它不起作用.显然它没有设置IPPROTO_IP/IP_MULTICAST_IF选项.我只能为IPPROTO_IP/IP_MULTICAST_IF找到boost :: asio :: ip :: multicast :: outbound_interface,我试过但失败了.有没有办法让boost :: asio :: ip :: multicast工作而不需要调用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));
Run Code Online (Sandbox Code Playgroud)

poo*_*per 5

正确答案:

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()));
Run Code Online (Sandbox Code Playgroud)

  • 什么是界面? (5认同)

ste*_*anB 5

我认为udp多播的boost示例代码中存在错误.

在示例代码中,它们将套接字绑定到本地接口,但对于udp多播,您必须绑定到udp多播组IP和端口.

socket_.bind(listen_endpoint);
Run Code Online (Sandbox Code Playgroud)

应该:

socket_.bind(
    boost::asio::ip::udp::endpoint( multicast_address, multicast_port ) );
Run Code Online (Sandbox Code Playgroud)

多播howto:

...对于接收多播数据报的进程,它必须要求内核加入该组并绑定那些数据报被发送到的端口.UDP层使用目标地址和端口来解复用数据包并决定将它们传递给哪个套接字...

...有必要告诉内核我们感兴趣的组播组.也就是说,我们必须要求内核"加入"这些组播组...

检查您是否在正确的界面上加入了该组 netstat -g | grep <multicast_group_ip>

这是我相信不正确的提升示例代码:

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));
Run Code Online (Sandbox Code Playgroud)