我试图使用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();
}
答案 0 :(得分:0)
您的第一个问题是Udefined Behaviour。
您对udp_find
类型的临时对象启动异步操作。该对象在构造后立即被破坏,因此即使在您开始任何异步工作(service.run()
)之前它也不再存在。
通过使udp_find
成为局部变量而不是临时变量,可以轻松解决这个问题:
udp_find op(service, 9000);
现在为我发送作品。您还需要测试接收工作。在我的netstat
输出中,似乎UDP套接字绑定到临时端口。将数据报发送到该端口使我的测试成功。
您可能希望在接收之前实际绑定/连接到广播地址(endpoint&
async_receive_from
参数而不是,我认为它是输出参数)。