Hi Gavin,
Yep, I ran a few tests where I ensured that two complete messages were received into a boost::asio::streambuf and confirmed that read_until '[' returned the SOP first index, read_until ']' returned the first EOP index, I then consume()'d those characters and repeated the call to read_until and confirmed it returned immediately based on the streambuf contents. So this all works as described by the documentation.
Yep. Just be careful if you're mixing calls to read_until with calls to read -- read_until may fetch a larger amount of data into the streambuf (beyond the delimiter), while read will always wait for new data, even if the streambuf isn't empty. So you need to explicitly check the streambuf before calling read().
Of course if you're only dealing with purely delimited data then this shouldn't be an issue, as you'll only be using [async_]read_until.
That is an interesting warning. I hadn't really thought about whether I could mix the blocking and non-blocking read commands (but would have assumed I should not!). The modified chat application uses using only the async versions, i.e., async_read_until, and async_write.
Once I finish my variation on the chat client/server, I'd be happy to post the code. At a minimum it would provide code for people on the list to review/comment on, and any final version of the code would benefit anyone interested in reading streams containing a different style of packet than that used in the boost example chat client/server.
Asio has a dedicated mailing list (https://lists.sourceforge.net/lists/listinfo/asio-users), which I believe the library maintainer pays closer attention to than this list; it may be worthwhile asking there.
Oh, good point. My code started in Boost.Iostreams, but now its in the Boost.Asio camp :)
Maybe you could even get it included in the official docs. :)
Yes, that was my hope. You can never have too many examples!
(I have some working streambuf code but it's not really in consumable-example form.)
Ok, so here's a streambuf question for you. In my attempt to
modify the chat server as much as possible, I initially modified
the buffering to use a streambuf member variable ... but that
fails, since a streambuf is non-copyable. My solution was to use
a shared_ptr<streambuf>> - see the chat_message.hpp code below.
Given that the shared_ptr is reference counted, when the server
'delivers' a read message to multiple clients, the shared pointer
reference count on a new message read from a client will increment
as its copied to each of the clients connected to a session, and
then decrement as each server client handler write pops the message
off its write queue.
At least I assume that is what is going on (I just finished
modifying the server and its working ok), I'll use the debugger
and trace the server code tomorrow to check.
Do you see anything wrong with using a shared_ptr<streambuf>
member variable? I wanted to use a streambuf so that I could
pass it directly to the async_read_until and async_write functions
(saving the buffer() conversions used in the original code).
Cheers,
Dave
//
// chat_message.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff
dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See
accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Chat client/server message coder/decoder.
//
// This is based on the Boost chat client/server example modified
// to use a different encoding/decoding method.
//
// The encoded message to send or receive is stored in a
// std::shared_ptrboost::asio::streambuf buffer_
// a shared pointer is used, since streambufs are non-copyable.
//
#ifndef CHAT_MESSAGE_HPP
#define CHAT_MESSAGE_HPP
#include