读取boost :: asio UDP广播响应

时间:2018-03-18 09:28:56

标签: c++ udp boost-asio

我试图使用boost :: asio来实现一个简单的设备发现协议。基本上我想发送一个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();
}

1 个答案:

答案 0 :(得分:0)

您的第一个问题是Udefined Behaviour

您对udp_find类型的临时对象启动异步操作。该对象在构造后立即被破坏,因此即使在您开始任何异步工作(service.run())之前它也不再存在。

通过使udp_find成为局部变量而不是临时变量,可以轻松解决这个问题:

udp_find op(service, 9000);

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

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