1

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....

NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277

2 Answers2

2

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).

Community
  • 1
  • 1
Tanner Sansbury
  • 51,153
  • 9
  • 112
  • 169
  • ah, so udp msgs get queued on the socket, and when I register a handler it pops one datagram of the socket q and gives ito the handler? async in the name confused me, i thought it is when you have data on this socket call me, if nothing is registered let data drop – NoSenseEtAl Jan 02 '14 at 19:47
  • @NoSenseEtAl: Basically, yes. [`async_*`](http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/asynchronous_operations.html) functions are _initiating functions_, and initiate a non-blocking operation; they do not cause state change (i.e. socket can no longer receive data). In the original code, the operation will read data into `recv_buffer_`, then use the result to invoke `udp_server::handle_receive()` handler with the appropriate `error` and `bytes_transferred` values. – Tanner Sansbury Jan 03 '14 at 13:46
1

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).

fredrik
  • 6,483
  • 3
  • 35
  • 45