c++ - 读取 boost::asio UDP 广播响应

标签 c++ udp boost-asio

我正在尝试使用 boost::asio 来实现一个简单的设备发现协议(protocol)。基本上我想发送一个带有 2 字节有效负载的广播消息(端口 9000)。然后读取设备的响应(假设当前存在)。在 wireshark 中,我可以看到广播已发送并且设备正在响应。但是,在我的示例代码中,我得到返回的字节数在 UDP 读取中是 0,而不是 30 字节的数据。

No.  Time      Source         Destination         Protocol  Length
1    0.00000   192.168.0.20   255.255.255.255     UDP       44        52271 -> 9000  Len = 2
2    0.00200   192.168.0.21   192.168.0.20        UDP       72        9000  -> 52271 Len = 30

我应该从不同于 broadcastEndpoint 的端点读取数据吗?我如何获得终点?

我是 asio 的新手,正在尝试自学,但我无法解决我做错的事情。

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

class udp_find {
public:
    udp_find(boost::asio::io_context& service, unsigned int port)
    : broadcastEndpoint_(boost::asio::ip::address_v4::broadcast(), port),
      socket_(service)
    {
        socket_.open(boost::asio::ip::udp::v4());
        socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
        socket_.set_option(boost::asio::socket_base::broadcast(true));

        boost::array<unsigned int, 2> data = {255, 255};
        socket_.async_send_to(
                          boost::asio::buffer(data, 2), broadcastEndpoint_,
                              boost::bind(&udp_find::handle_send, this,
                                          boost::asio::placeholders::error,
                                          boost::asio::placeholders::bytes_transferred));
}

void handle_receive(const boost::system::error_code& error,
                    std::size_t bytes_transferred)
{
    std::cout << "Received Data" << bytes_transferred << std::endl;
}

void handle_send(const boost::system::error_code& error, std::size_t bytes_transferred)
{
    std::cout << "Sent Data"  << bytes_transferred << std::endl;

    socket_.async_receive_from(
                               boost::asio::buffer(buffer_), broadcastEndpoint_,
                               boost::bind(&udp_find::handle_receive, this,
                                           boost::asio::placeholders::error,
                                               boost::asio::placeholders::bytes_transferred));
    }

private:
    boost::asio::ip::udp::socket socket_;
    boost::array<char, 128> buffer_;
    boost::asio::ip::udp::endpoint broadcastEndpoint_;
};

int main()
{
    boost::asio::io_context service;
    udp_find(service, 9000);
    service.run();
}

最佳答案

你的第一个问题是Udefined Behaviour .

您对 udp_find 类型的临时对象启动异步操作。该对象在构造后立即销毁,因此甚至在您开始任何异步工作 (service.run()) 之前它就不再存在了。

通过将 udp_find 设为局部变量而不是临时变量,可以很容易地解决这个问题:

udp_find op(service, 9000);

现在为我发送作品。您还需要测试接收是否有效。在我的 netstat 输出中,UDP 套接字似乎绑定(bind)到临时端口。向该端口发送数据报使我的测试成功。

您可能希望在接收之前实际绑定(bind)/连接到广播地址(async_receive_fromendpoint& 参数不是,我认为它是一个输出参数)。

关于c++ - 读取 boost::asio UDP 广播响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49346350/

相关文章:

c++ - std::vector<Simd_wrapper> 是否在内存中有连续的数据?

c++ - 返回 const int* 与返回 const int* 引用

C++ 运算符优先级?

linux - socket()系统调用中参数protocol代表什么?

c++ - boost asio 打开更多的一个套接字

multithreading - boost asio 处理程序中的长时间运行/阻塞操作

c++ - 在程序关闭期间终止 Qt 工作线程

c# - 将方法存储在自定义 Tcp 或 Udp 服务器的字典中。这是个好主意吗? C#

java - 通过 UDP 将 C 结构转换为 Java 对象

c++ - 调试和自由执行中的信号处理