11

I'm reading from a boost::asio::ip::udp::socket like this:

using boost::asio::ip::udp;

// ...

char recv_buf[128];
udp::endpoint sender_endpoint;
size_t len = socket.receive_from(boost::asio::buffer(recv_buf), sender_endpoint);

Now, this works perfectly fine, but the maximum amount of characters that I am able to recieve is now 127. However I am facing a problem because I need to accept some data input of which the length can greatly vary (and is not of well-defined length with prefixed headers, for example). A solution to this would be a dynamically expanding buffer, like a vector. Is it possible to create a dynamically expanding boost::asio::buffer to accept (theoretical) infite amounts of input and store it in a container?

orlp
  • 112,504
  • 36
  • 218
  • 315

4 Answers4

5

UDP datagram size does not vary all that greatly: it will never be greater than 65535, leaving room for 65,527 bytes of data after the 8-byte header.

cjs
  • 25,752
  • 9
  • 89
  • 101
Cubbi
  • 46,567
  • 13
  • 103
  • 169
  • 1
    +1 You are totally right! Still I would be interested in a dynamic `boost::asio::buffer`, not because 64KiB is so huge, but a dynamic buffer often seems a lot more appropriate, and for reuse in TCP. – orlp May 08 '11 at 23:19
  • @nightcracker with TCP, asio calls the read handler when the buffer is full, so you can empty it and return to reading. – Cubbi May 08 '11 at 23:20
2

Boost 1.66.0 added dynamic_buffer which can adapt a reference to std::string or std::vector<CharType>:

sehe
  • 374,641
  • 47
  • 450
  • 633
1

If you use smaller buffers, you can easily chain them together via the *BufferSequences concepts. For example, you can pass in a MutableBufferSequence to accept data from a read(2) call or pass a ConstBufferSequence for a list of buffers that you are going to write(2) out. That said, I tend to recommend using a single buffer in each direction because it tends to simplify code (though that's not always possible).

Sean
  • 9,888
  • 4
  • 40
  • 43
0

There does not appear to be any provision for dynamic sizing. And it makes sense that there would not be. Think about what would have to happen:

  • A single UDP datagram can only be received once, and at once, therefore:
  • the buffer given to the low-level system call needs to be large enough for the largest valid message, so,
  • for it to be efficient, the buffer must be allocated up-front by the caller.

So it does not make sense for there to be a dynamically-sized buffer available. As Cubbi points out, UDP datagrams have a smallish maximum size anyway, so just make your buffer as large as the largest valid message in your system and be done with it.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • 3
    `boost::asio::buffer` is a general ASyncronous Input/Output buffer, and is not only used for UDP. – orlp May 08 '11 at 23:24
  • Sure. And in general it does not make sense to have a dynamic one. Neither for your application nor for TCP nor any other protocol which eventually calls the low-level C routines to do their work, because it will only lead to inefficient memory copying, which anathema in C++ and in Boost. – John Zwinck May 08 '11 at 23:25