Hiya,
I'm currently using asio to read from a socket into a boost::array, and then parsing the fields out. It works but it's a little ugly, and it's prone to breaking.
I've read about using asio::streambuf instead, which seems to be exactly what i need - receive the data, use an istream to pull out the fields and go.
The documentation isn't completely clear to me though - am I expected to read into a single streambuf for each socket, and copy each 'message' out into another array to pass around as needed? Or is it OK to read into a new streambuf for each message, and pass the streambuf itself around inside my application?
Many thanks for any advice.
Cheers, James
Boost asio streambuf?
Started by Telios, Jan 31 2012 09:01 PM
5 replies to this topic
Ad:
#2 Moderators - Reputation: 1800
Posted 01 February 2012 - 09:48 PM
You can create new streambufs for each call to read. The main thing to watch out for is that you may be reading more than you need for just your packet -- there may be data left in the streambuf that's the start of the next packet (at least if you're using TCP -- with UDP, you get exactly one datagram per streambuf)
enum Bool { True, False, FileNotFound };
#3 Members - Reputation: 230
Posted 02 February 2012 - 07:39 AM
Brilliant, thanks.
Portfolio & Interests: http://www.jamesbb.co.uk
#4 Members - Reputation: 230
Posted 04 February 2012 - 01:58 PM
I'm having a little trouble with this.
Each message comprises it's size, followed by the data. In the async_read() handler, I'm parsing out the message size and posting another read if the last message's data isn't all there, using transfer_at_least().
When the handler is called again with the rest of the data, I then have no way of knowing the size of the incomplete message, as the size field was removed from the stream by the previous handler.
Is there a way of reading bytes from a streambuf without removing them, so I can leave the size field intact in the buffer?
Any help appreciated
Each message comprises it's size, followed by the data. In the async_read() handler, I'm parsing out the message size and posting another read if the last message's data isn't all there, using transfer_at_least().
When the handler is called again with the rest of the data, I then have no way of knowing the size of the incomplete message, as the size field was removed from the stream by the previous handler.
Is there a way of reading bytes from a streambuf without removing them, so I can leave the size field intact in the buffer?
Any help appreciated
Portfolio & Interests: http://www.jamesbb.co.uk
#5 Moderators - Reputation: 1800
Posted 06 February 2012 - 03:55 PM
Note that transfer_at_least may transfer more than you request.
The best way to do this is to just use ASIO to snarf data from the network into a big cyclic buffer (perhaps virtual?) and then parse the length and packets out of that. All ASIO needs to do is try to fill the buffer with data. In the callback for "I got more data," you can check how many complete packets there are in the buffer at the time of the callback, dequeue any packets that are complete and dispatched, and then try to re-fill the buffer with more data.
There is a buffer class in ASIO that may be better than the streambuf class.
The best way to do this is to just use ASIO to snarf data from the network into a big cyclic buffer (perhaps virtual?) and then parse the length and packets out of that. All ASIO needs to do is try to fill the buffer with data. In the callback for "I got more data," you can check how many complete packets there are in the buffer at the time of the callback, dequeue any packets that are complete and dispatched, and then try to re-fill the buffer with more data.
There is a buffer class in ASIO that may be better than the streambuf class.
enum Bool { True, False, FileNotFound };
#6 Members - Reputation: 230
Posted 06 February 2012 - 09:29 PM
Aha, thanks - that's a good solution.
Cheers!
Cheers!
Portfolio & Interests: http://www.jamesbb.co.uk


















