Reading a UDP socket twice discards the remaining bytes after the first call

My goal is to read data from a UDP socket in two steps. The problem is that if I write more data to the socket than it reads in the first step. As a result, the remaining data disappears.

I reduced the code to the following snippet:

#include <boost/asio/ip/udp.hpp>
using namespace boost::asio;

int main() {
  io_service net_io;
  ip::udp::socket net_sock( net_io, ip::udp::endpoint( ip::udp::v4(), 1234 ) );

  uint8_t data[2];

  net_sock.receive( buffer( data, 2 ) );
  std::cout << data[0] << data[1] << std::endl;

  net_sock.receive( buffer( data, 2 ) );
  std::cout << data[0] << data[1] << std::endl;


  net_sock.close();
  return EXIT_SUCCESS;
}

When I write data to a socket as follows:

echo '0123456789' | nc -u localhost 1234

The program displays the first two bytes 01, and then blocks. Instead, I was expecting an exit:

01
23

However, it is blocked in the second call receive(). According to the manual :

The call will be blocked until one of the following conditions is met:

∙ The supplied buffers are full. [...]
∙ An error has occurred.

Why is the buffer empty? If I run

echo '0123456789' | nc -u localhost 1234

, receive() , 01. 23456789, , receive() ?

: , , ( ) .

+5
1

UDP - - . .

- " ". , write send . read recv, , , .

.

, . , , .

, , UDP , - . , , , .

- :

#include <boost/asio/ip/udp.hpp>
using namespace boost::asio;

const unsigned int max_datagram_size = 65536;

int main() {
  io_service net_io;
  ip::udp::socket net_sock( net_io, ip::udp::endpoint( ip::udp::v4(), 1234 ) );

  uint8_t data[max_datagram_size];

  // I like declaring all values that I do not expect to change as const.
  const int recved_size = net_sock.receive( buffer( data, max_datagram_size ) );
  if (recved_size >= 0) {
    std::cout << ::std::string(data, recved_size) << '\n';
  } else {
    std::cout << "There was some sort of error receiving data.\n";
  }


  net_sock.close();
  return EXIT_SUCCESS;
}
+5

All Articles