为什么此示例使用 ASIO async_receive_from不"leaky"

Why is this example using ASIO async_receive_from not "leaky"

本文关键字:receive from leaky async ASIO 为什么      更新时间:2023-10-16

基本上:

void start_receive()
{
socket_.async_receive_from(
boost::asio::buffer(recv_buffer_), remote_endpoint_,
boost::bind(&udp_server::handle_receive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_receive(const boost::system::error_code& error,
std::size_t /*bytes_transferred*/)
{
if (!error || error == boost::asio::error::message_size)
{
boost::shared_ptr<std::string> message(
new std::string(make_daytime_string()));
socket_.async_send_to(boost::asio::buffer(*message), remote_endpoint_,
boost::bind(&udp_server::handle_send, this, message,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
start_receive();
}
}

发件人:http://www.boost.org/doc/libs/1_35_0/doc/html/boost_asio/tutorial/tutdaytime6/src.html

根据我的理解,start_recive注册handle_recive,然后当调用handle_receive时,如果一切正常,则再次调用start_receive以重新注册,并重复此操作。我不明白的是,数据是否有可能在调用handle_receive和handle_receivecalls start_receive之间滑动。。。。

这在技术上是可能的,但不太可能发生在非饱和条件下的udp_server示例中。

虽然Boost.Asio在套接字上可能没有任何挂起的读取操作,但操作系统的网络堆栈将在内核内存中对接收到的数据进行排队。Boost.Asio的异步操作使用一个反应器来通知网络堆栈何时可以在给定的套接字上读取数据。处理完此通知后,Boost.Asio将启动从套接字的读取,从而将数据从网络堆栈的内核内存复制到所提供的用户内存中。

内核的网络堆栈和套接字通常有一个可配置的参数来控制它们的最大缓冲区大小。例如,receive_buffer_size套接字选项、Windows注册表或Linuxsysctl。在这种内存限制和UDP不具有传递保证的情况下,如果数据报以比产生(接收)数据报慢的速率被消耗(读取),则网络堆栈可能丢弃数据报。

socket_有一个缓冲区,用于存储传入数据,直到读取。在示例中udp_server的构造函数中,udp套接字被初始化为侦听端口13。

侦听器服务主要是通过io_service.run()调用(通常不会返回)启动的。