gpt4 book ai didi

c++ - 使用 boost::asio 获取 UDP 套接字远程地址

转载 作者:行者123 更新时间:2023-11-30 05:03:28 37 4
gpt4 key购买 nike

我想获取响应UDP广播的设备的IP地址。在下面的代码中,我执行 UDP 广播来查找设备。当设备响应时,我尝试使用 remote_endpoint() 获取远程端点。

但是应用程序异常崩溃 boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >: remote_endpoint: Socket is not connected

因为我是 C++ 和 boost::asio 的新手,有人可以解释我需要更改代码以获取远程端点的 IP 地址的内容。

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

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

find();
}

void find () {
std::array<unsigned int, 2> data = {255, 255};
for (auto it = std::begin(data); it != std::end(data); ++it)
std::cout << *it;
socket_.async_send_to(
boost::asio::buffer(data, 2), broadcastEndpoint_,
boost::bind(&udpFind::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)
{
// Read has finished, so cancel the timer.
timer.cancel();
if (!error) {
std::cout << "Received Data" << bytes_transferred << std::endl

boost::asio::ip::udp::endpoint local_ep = socket_.local_endpoint();
boost::asio::ip::udp::endpoint remote_ep = socket_.remote_endpoint();
}
}

void handle_retry(const boost::system::error_code& error) {
std::cout << "retrying" << std::endl;
find();
}


void handle_timeOut(const boost::system::error_code& error) {
if (!error) {
std::cout << "Timeout" << std::endl;
// Timer has expired cancel read operation
socket_.cancel();
timer.expires_from_now(boost::posix_time::milliseconds(10000));
timer.async_wait(boost::bind(&udpFind::handle_retry,
this, boost::asio::placeholders::error));
}
}


void handle_send(const boost::system::error_code& error, std::size_t bytes_transferred)
{
std::cout << "Sent Data " << bytes_transferred << std::endl;
buffer_= {};
socket_.async_receive_from(
boost::asio::buffer(buffer_), broadcastEndpoint_,
boost::bind(&udpFind::handle_receive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));

timer.expires_from_now(boost::posix_time::milliseconds(10000));
timer.async_wait(boost::bind(&udpFind::handle_timeOut,
this, boost::asio::placeholders::error));
}

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

int main()
{
boost::asio::io_context service;
boost::asio::ip::udp::endpoint listen_endpoint(boost::asio::ip::address::from_string("0.0.0.0"), 0);
udpFind find(service, listen_endpoint, 9000);
service.run();
}

最佳答案

我提到了 the other day : async_receive_from 的端点和参数不是为了那个,我认为它是一个输出参数”

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

在这里,您传递了对 broadcastEndpoint 的引用,这可能不是您想做的。 The documentation states该参数是 sender_endpoint:

  • sender_endpoint

    An endpoint object that receives the endpoint of the remote sender of the datagram. Ownership of the sender_endpoint object is retained by the caller, which must guarantee that it is valid until the handler is called.

因此,解决方案是简单地添加一个变量来接收远程端点:

Live On Coliru

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

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

find();
}

void find () {
std::array<unsigned int, 2> data = {{255, 255}};
for (auto it = std::begin(data); it != std::end(data); ++it)
std::cout << *it;

socket_.async_send_to(
boost::asio::buffer(data, 2), broadcastEndpoint_,
boost::bind(&udpFind::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)
{
// Read has finished, so cancel the timer.
timer.cancel();
if (!error) {
std::cout << "Received Data" << bytes_transferred << " from " << senderEndpoint_ << std::endl;
}
}

void handle_retry(const boost::system::error_code& error) {
std::cout << "retrying" << std::endl;
find();
}


void handle_timeOut(const boost::system::error_code& error) {
if (!error) {
std::cout << "Timeout" << std::endl;
// Timer has expired cancel read operation
socket_.cancel();
timer.expires_from_now(boost::posix_time::milliseconds(10000));
timer.async_wait(boost::bind(&udpFind::handle_retry,
this, boost::asio::placeholders::error));
}
}


void handle_send(const boost::system::error_code& error, std::size_t bytes_transferred)
{
std::cout << "Sent Data " << bytes_transferred << " (" << error.message() << ")" << std::endl;
buffer_= {};
socket_.async_receive_from(
boost::asio::buffer(buffer_), senderEndpoint_,
boost::bind(&udpFind::handle_receive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));

timer.expires_from_now(boost::posix_time::milliseconds(10000));
timer.async_wait(boost::bind(&udpFind::handle_timeOut,
this, boost::asio::placeholders::error));
}

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

int main()
{
boost::asio::io_context service;
boost::asio::ip::udp::endpoint listen_endpoint(boost::asio::ip::address::from_string("0.0.0.0"), 0);
udpFind find(service, listen_endpoint, 9000);
service.run();
}

关于c++ - 使用 boost::asio 获取 UDP 套接字远程地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49400978/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com