A while back, I asked a question about receiving datagrams in batches using asio. Since, as it turns out, I can't do that, I have another question: Is it possible to decouple the packet reception from the socket creation logic in asio?
I'm still using the same server from my previous question. Let's take a look at the most important part receiving messages:
// main receive function
void do_receive()
{
socket_.async_receive_from(
asio::buffer(data_, max_length), sender_endpoint_,
[this](std::error_code ec, std::size_t bytes_recvd)
{
if (ec == asio::error::operation_aborted)
return;
if (ec)
std::cerr << "error recv: " << ec.message() << '\n';
else if (bytes_recvd > 0)
handle(bytes_recvd);
// receive more
do_receive();
});
}
We have a call to the async_receive_from function, one of whose arguments is a lambda function (our completion handler). The problem with this code is that it’s essentially isolated. Inside the completion handler, we call this function again. And we continue receiving messages. I'd like to have code something like this:
// Our UDP server
class UdpServer {
// ctor && dctor && other methods like join_multicast
private:
asio::io_context m_ctx; // todo: or better to store it outside of server?
asio::ip::idp::socket m_sock;
}
// Another place in my code
class AnotherPlace {
// every time UdpServer received new packet this function is called
void packet_received(Packet& packet) {
}
}
Is that possible? We now have a completely separate area for receiving packets and can process them there. We no longer process them directly on the server, which I consider bad practice, because the server shouldn't be parsing packets.