简体   繁体   中英

Why is this example using ASIO async_receive_from not “leaky”

Basically:

  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();
    }
  }

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

From what I understand start_recive registers handle_recive , then handle_receive when called if everything is ok calls start_receive again to be reregistered and that is repeated. Thing I dont understand isnt there a possibility that data may slip between call to handle_receive and the time handle_receive calls start_receive again....

It is technically possible, but not likely to occur for the udp_server example in non-saturated conditions.

Although Boost.Asio may not have any pending read operations on a socket, the operating system's network stack will queue received data in kernel memory. Boost.Asio's asynchronous operations use a reactor to be notified when the network stack has data available for reading on a given socket. Once this notification has been processed, Boost.Asio will initiate a read from the socket, causing data to be copied from the network stack's kernel memory into the provided user memory.

The kernel's network stack and sockets often have a configurable parameter that controls their maximum buffer size. For example, the receive_buffer_size socket option, Windows registry , or Linux sysctl . With this memory limitation and UDP not having a guarantee of delivery, the network stack may drop datagrams if datagrams are being consumed (read) at a slower rate than which they are produced (received).

The socket_ has a buffer which stores incoming data until read. In the constructor of udp_server in the example udp socket is initialized to listen on port 13.

The listener service is started in main, with the io_service.run() call (which doesn't normally return).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM