提升ASIO超时方法
我有需要在100毫秒内收集100多个客户的数据。在那段时间之后,我需要处理收集的数据。完成过程后,需要重新启动我从客户端收集数据的位置,等等。
要收集我正在使用当前实施的数据:
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
#include <list>
#include <set>
namespace net = boost::asio;
using net::ip::udp;
using boost::system::error_code;
using namespace std::chrono_literals;
using namespace std::placeholders;
struct listener {
using Buffer = std::array<char, 100>; // receiver buffer
udp::socket s;
listener(net::any_io_executor ex, uint16_t port) : s{ex, {{}, port}} {}
void start() {
read_loop(error_code{}, -1); // prime the async pump
}
void stop() {
post(s.get_executor(), [this] { s.cancel(); });
}
void report() const {
std::cout << s.local_endpoint() << ": A total of " << received_packets
<< " were received from " << unique_senders.size()
<< " unique senders\n";
}
private:
Buffer receive_buffer;
udp::endpoint sender;
std::set<udp::endpoint> unique_senders;
size_t received_packets = 0;
void read_loop(error_code ec, size_t bytes) {
if (bytes != size_t(-1)) {
// std::cout << "read_loop (" << ec.message() << ")\n";
if (ec)
return;
received_packets += 1;
unique_senders.insert(sender);
std::cout << "Received:" << bytes << " sender:" << sender << " recorded:"
<< received_packets << "\n";
//std::cout <<
// std::string_view(receive_buffer.data(), bytes) << "\n";
}
s.async_receive_from(net::buffer(receive_buffer), sender,
std::bind_front(&listener::read_loop, this));
};
};
int main() {
net::thread_pool io(1); // single threaded
using Timer = net::steady_timer;
using TimePoint = std::chrono::steady_clock::time_point;
using Clock = std::chrono::steady_clock;
Timer timer_(io);
std::list<listener> listeners;
auto each = [&](auto mf) { for (auto& l : listeners) (l.*mf)(); };
for (uint16_t port : {1234, 1235, 1236})
listeners.emplace_back(io.get_executor(), port);
each(&listener::start);
TimePoint startTP = Clock::now();
timer_.expires_at(startTP + 100ms); // collect data for 100 ms
timer_.async_wait([&](auto &&){each(&listener::stop);});
std::cout << "Done ! \n";
each(&listener::report);
io.join();
}
可以停止收集过程的方法吗?
TimePoint startTP = Clock::now();
timer_.expires_at(startTP + 100ms); // collect data for 100 ms
timer_.async_wait([&](auto &&){each(&listener::stop);});
I have situation where I need to collect data from more than 100 clients in 100 ms. After that time I need to process collected data. When process is done, need to restart step where I am collecting data from the clients and so on in the loop.
To collect the data I am using the current implementation :
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
#include <list>
#include <set>
namespace net = boost::asio;
using net::ip::udp;
using boost::system::error_code;
using namespace std::chrono_literals;
using namespace std::placeholders;
struct listener {
using Buffer = std::array<char, 100>; // receiver buffer
udp::socket s;
listener(net::any_io_executor ex, uint16_t port) : s{ex, {{}, port}} {}
void start() {
read_loop(error_code{}, -1); // prime the async pump
}
void stop() {
post(s.get_executor(), [this] { s.cancel(); });
}
void report() const {
std::cout << s.local_endpoint() << ": A total of " << received_packets
<< " were received from " << unique_senders.size()
<< " unique senders\n";
}
private:
Buffer receive_buffer;
udp::endpoint sender;
std::set<udp::endpoint> unique_senders;
size_t received_packets = 0;
void read_loop(error_code ec, size_t bytes) {
if (bytes != size_t(-1)) {
// std::cout << "read_loop (" << ec.message() << ")\n";
if (ec)
return;
received_packets += 1;
unique_senders.insert(sender);
std::cout << "Received:" << bytes << " sender:" << sender << " recorded:"
<< received_packets << "\n";
//std::cout <<
// std::string_view(receive_buffer.data(), bytes) << "\n";
}
s.async_receive_from(net::buffer(receive_buffer), sender,
std::bind_front(&listener::read_loop, this));
};
};
int main() {
net::thread_pool io(1); // single threaded
using Timer = net::steady_timer;
using TimePoint = std::chrono::steady_clock::time_point;
using Clock = std::chrono::steady_clock;
Timer timer_(io);
std::list<listener> listeners;
auto each = [&](auto mf) { for (auto& l : listeners) (l.*mf)(); };
for (uint16_t port : {1234, 1235, 1236})
listeners.emplace_back(io.get_executor(), port);
each(&listener::start);
TimePoint startTP = Clock::now();
timer_.expires_at(startTP + 100ms); // collect data for 100 ms
timer_.async_wait([&](auto &&){each(&listener::stop);});
std::cout << "Done ! \n";
each(&listener::report);
io.join();
}
Is it okay approach to stop collecting process ?
TimePoint startTP = Clock::now();
timer_.expires_at(startTP + 100ms); // collect data for 100 ms
timer_.async_wait([&](auto &&){each(&listener::stop);});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我将其解释为基本上是在询问如何组合
-no-incoming-data/72015194?noredirect = 1#comment127835948_72015194“> :
使用我在第一个(单个列表)示例中使用的相同时板计算似乎容易得多。
我计算时间切片的方式的全部要点是允许在没有时间段的情况下将同步到一个时钟。它的优点在于,它在多上名单上翻译了1:1。
这是每个侦听器与1个计时器的组合,但同步的时间切片,以完全相同的方式创建了我从原始答案代码中创建多上述式示例的方式:
in Coliru
live
href =“ https://i.sstatic.net/g3ucu.gif” rel =“ nofollow noreferrer”>
编辑以防输出太快而无法解释:
如果您是确定您仍保持单线螺纹,则可以考虑使用相同的实际计时器,以显着提高复杂性的成本。
I'm interpreting this as basically asking how to combine
This is also reflected in your comment there:
It would seem much easier to use the same time-slice calculation I used in the first (single-listener) example.
The whole point of the way I calculated time slices was to allow for synchronization to a clock, without time-drift. The beauty of it is that it translates 1:1 on multi-listeners.
Here's the combination with 1 timer per listener but synchronized time slices, created in exactly the same way I created the multi-listener sample from the original answer code:
Live On Coliru
Live Demo:
EDIT In case the output goes too fast to interpret:
If you are sure you are remaining single threaded, you might consider using the same actual timer, at the cost of significantly increasing complexity.