C++使用Boost库加入UDP组播时程序崩溃

程序崩溃情况

  • 本程序运行在Oracle VM VirtualBox虚拟的Ubuntu20.04

    terminate called after throwing an instance of ‘boost::wrapexceptboost::system::system_error’ what(): set_option: No such device 已放弃 (核心已转储) **

  • C++使用Boost库加入组播的代码

#include <iostream>
#include <boost/asio.hpp>

class MulticastReceiver
{
public:
    MulticastReceiver(boost::asio::io_context &ioContext, const std::string &multicastAddress, const std::string &listenAddress, int port)
        : ioContext(ioContext),
          socket(ioContext),
          multicastEndpoint(boost::asio::ip::address::from_string(multicastAddress), port),
          listenEndpoint(boost::asio::ip::address::from_string(listenAddress), port)
    {
        // 创建套接字
        socket.open(listenEndpoint.protocol());

        // 设置套接字选项,允许地址重用
        socket.set_option(boost::asio::ip::udp::socket::reuse_address(true));

        // 绑定到监听地址
        socket.bind(listenEndpoint);

        // 加入组播组
        socket.set_option(boost::asio::ip::multicast::join_group(multicastEndpoint.address()));
    }

    void start()
    {
        receive();
    }

private:
    void receive()
    {
        socket.async_receive_from(boost::asio::buffer(buffer), senderEndpoint,
                                  [this](const boost::system::error_code &error, std::size_t bytesTransferred)
                                  {
                                      if (!error)
                                      {
                                          // 处理接收到的数据
                                          std::cout << "Received: " << std::string(buffer.data(), bytesTransferred) << std::endl;

                                          // 继续接收数据
                                          receive();
                                      }
                                      else
                                      {
                                          std::cerr << "Error receiving data: " << error.message() << std::endl;
                                      }
                                  });
    }

private:
    boost::asio::io_context &ioContext;
    boost::asio::ip::udp::socket socket;
    boost::asio::ip::udp::endpoint multicastEndpoint;
    boost::asio::ip::udp::endpoint listenEndpoint;
    std::array<char, 1024> buffer;
    boost::asio::ip::udp::endpoint senderEndpoint;
};

  • Boost库报错信息时No such device

Boost库中boost::asio::ip::udp::socket套接字找不到网卡去加入组播。

  • 设置默认路由即可解决程序崩溃问题
route add -net 0.0.0.0 netmask 0.0.0.0 dev enp0s3
  • 查看路由表
    在这里插入图片描述
Linux系统中必须设置0.0.0.0的默认路由规则,否则程序加入组播时会宕掉。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用 Boost 接收 UDP 组播和单播数据的主要区别有以下几点: 1. 组播需要设置套接字的 TTL(Time-To-Live)选项,以确定数据包的最大传输距离。 2. 组播需要加入组播组,以接收特定的组播数据。 3. 单播需要设置远程地址和端口号,以接收特定的单播数据。 下面是一些示例代码,以说明如何使用 Boost 接收 UDP 组播和单播数据。 ### 接收 UDP 组播数据 以下示例代码演示了如何使用 Boost 接收 UDP 组播数据: ```c++ #include <iostream> #include <boost/asio.hpp> #include <boost/array.hpp> using boost::asio::ip::udp; int main() { try { boost::asio::io_context io_context; // 创建 UDP 套接字 udp::socket socket(io_context, udp::endpoint(udp::v4(), 12345)); // 设置 TTL 选项 socket.set_option(boost::asio::ip::multicast::hops(1)); // 加入组播udp::endpoint multicast_endpoint(boost::asio::ip::address::from_string("239.255.0.1"), 12345); socket.set_option(boost::asio::ip::multicast::join_group(multicast_endpoint.address())); // 接收数据 boost::array<char, 1024> recv_buffer; udp::endpoint sender_endpoint; size_t len = socket.receive_from(boost::asio::buffer(recv_buffer), sender_endpoint); // 打印接收到的数据 std::cout.write(recv_buffer.data(), len); } catch (std::exception& e) { std::cerr << e.what() << std::endl; } return 0; } ``` ### 接收 UDP 单播数据 以下示例代码演示了如何使用 Boost 接收 UDP 单播数据: ```c++ #include <iostream> #include <boost/asio.hpp> #include <boost/array.hpp> using boost::asio::ip::udp; int main() { try { boost::asio::io_context io_context; // 创建 UDP 套接字 udp::socket socket(io_context, udp::endpoint(udp::v4(), 12345)); // 接收数据 boost::array<char, 1024> recv_buffer; udp::endpoint sender_endpoint; size_t len = socket.receive_from(boost::asio::buffer(recv_buffer), sender_endpoint); // 打印接收到的数据 std::cout.write(recv_buffer.data(), len); } catch (std::exception& e) { std::cerr << e.what() << std::endl; } return 0; } ``` 注意,这两个示例代码非常相似,唯一的区别在于组播示例代码需要设置 TTL 选项和加入组播组。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晓琴儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值