[英]How can I add an async timer to a boost UDP server?
I got this code online and have been trying to add a timer to it so that it reads a packet every so often. 我将此代码在线获取,并一直在尝试向其添加计时器,以使其每隔一段时间读取一次数据包。 I can't seem to figure out how to pass a callback function to the boost::async_wait command because I am getting this error:
我似乎无法弄清楚如何将回调函数传递给boost :: async_wait命令,因为出现此错误:
server1.cpp: In member function ‘void UDPClient::handle_receive(const boost::system::error_code&, size_t)’:
server1.cpp:51:66: error: invalid use of non-static member function ‘void UDPClient::time_to_receive(const boost::system::error_code&)’
boost::asio::placeholders::error));
^
server1.cpp:33:6: note: declared here
void UDPClient::time_to_receive(const boost::system::error_code& error)
^~~~~~~~~
UDPClient Class: UDPClient类别:
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>
#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>
using boost::asio::ip::udp;
class UDPClient
{
public:
boost::asio::io_service io_service;
udp::socket socket;
udp::endpoint receiver_endpoint;
boost::asio::deadline_timer timer;
boost::array<char, 1024> recv_buffer;
UDPClient();
void time_to_receive(const boost::system::error_code& error);
void do_receive();
void handle_receive(const boost::system::error_code& error, size_t);
};
UDPClient::UDPClient()
: io_service(),
socket(io_service, {udp::v4(), 3643}),
timer(io_service, boost::posix_time::seconds(2))
{
do_receive();
io_service.run();
}
void UDPClient::time_to_receive(const boost::system::error_code& error)
{
do_receive();
}
void UDPClient::do_receive()
{
socket.async_receive_from(boost::asio::buffer(recv_buffer), receiver_endpoint,
boost::bind(&UDPClient::handle_receive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void UDPClient::handle_receive(const boost::system::error_code& error, size_t bytes_transferred)
{
std::cout << "Received: '" << std::string(recv_buffer.begin(), recv_buffer.begin()+bytes_transferred) << "'\n";
timer.async_wait(boost::bind(time_to_receive,
boost::asio::placeholders::error));
}
int main()
{
UDPClient updclient;
}
One question I'm trying to answer with this code is if I spam the server from a client with a bunch of UDP packets will the server ignore all the packets during the async_wait? 我要用此代码回答的一个问题是,如果我从一堆带有UDP数据包的客户端向服务器发送垃圾邮件,服务器会在async_wait期间忽略所有数据包吗?
Also, my main goal is to put this code into a quadcopter code I have. 另外,我的主要目标是将此代码放入我拥有的四旋翼代码中。 Will it work the way it is written to instantiate this class and have it read packets from a ground station to get user input?
它会以实例化此类的方式编写,并使其从地面站读取数据包以获取用户输入吗?
The way you use bind
with member function is wrong. 您使用与成员函数
bind
的方法是错误的。 Use it like shown below: 如下所示使用它:
timer.async_wait(boost::bind(&UDPClient::time_to_receive, this,
boost::asio::placeholders::error));
As to why it is like that, I would recommend you to read the boost docs for that. 至于为什么会这样,我建议您阅读该文档。
Also, I have modified the code to make it actually run like a server without exiting. 另外,我修改了代码,使其实际上像服务器一样运行而没有退出。 For that I made following 2 changes:
为此,我做了以下2处更改:
io_service
in main function and pass its reference to the class. io_service
并将其引用传递给该类。 io_service_work
object. io_service_work
对象。 This acts as a perennial source of work to the io_service
. io_service
的长期工作来源。 Thus, io_service
never returns from the run
function unless the work
object is destroyed. work
对象被销毁,否则io_service
永远不会从run
函数返回。 The complete source: 完整的来源:
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>
#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>
using boost::asio::ip::udp;
class UDPClient
{
public:
boost::asio::io_service& io_service;
udp::socket socket;
udp::endpoint receiver_endpoint;
boost::asio::deadline_timer timer;
boost::array<char, 1024> recv_buffer;
UDPClient(boost::asio::io_service&);
void time_to_receive(const boost::system::error_code& error);
void do_receive();
void handle_receive(const boost::system::error_code& error, size_t);
};
UDPClient::UDPClient(boost::asio::io_service& ios)
: io_service(ios),
socket(io_service, {udp::v4(), 3643}),
timer(io_service, boost::posix_time::seconds(2))
{
do_receive();
}
void UDPClient::time_to_receive(const boost::system::error_code& error)
{
do_receive();
}
void UDPClient::do_receive()
{
socket.async_receive_from(boost::asio::buffer(recv_buffer), receiver_endpoint,
boost::bind(&UDPClient::handle_receive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void UDPClient::handle_receive(const boost::system::error_code& error, size_t bytes_transferred)
{
std::cout << "Received: '" << std::string(recv_buffer.begin(), recv_buffer.begin()+bytes_transferred) << "'\n";
timer.expires_from_now(boost::posix_time::seconds(2));
timer.async_wait(boost::bind(&UDPClient::time_to_receive, this,
boost::asio::placeholders::error));
}
int main()
{
boost::asio::io_service ios;
boost::asio::io_service::work wrk(ios);
UDPClient updclient(ios);
ios.run();
}
NOTE: Even though it is a server, the class is name Client. 注意:即使它是服务器,该类也是名称Client。 I am ignoring that :)
我忽略了:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.