我正在尝试使用 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_from
的endpoint&
参数不是,我认为它是一个输出参数)。
关于c++ - 读取 boost::asio UDP 广播响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49346350/