Note that there are some explanatory texts on larger screens.

plurals
  1. POboost::asio::async_read into boost::asio::streambuf blocks when streambuf is populated by previous async_read
    primarykey
    data
    text
    <p>I have searched other posts, but didn't found anything relevant. Now, I have a protocol consisting of header and body. Protocol is like: Z24,91009802,123456789ABCDEF Where Z24, is the header. Z is message type, 24 is remaining bytes to read. Remaining bytes is variable, so I read until first ',' is found.</p> <pre><code>void handle_handshake(const boost::system::error_code&amp; error) { if (!error) { boost::asio::async_read_until( socket_, inputStreamBuffer_, ',', boost::bind( &amp;session::doReadHeader, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred) ); } else { delete this; } } void doReadHeader( const boost::system::error_code&amp; error, size_t bytes_transferred) { if (!error) { istream is(&amp;inputStreamBuffer_); vector&lt;char&gt; v(bytes_transferred); is.read(&amp;(v[0]),bytes_transferred); request_.append(v.begin(),v.end()); cout &lt;&lt; "request_=#" &lt;&lt; request_ &lt;&lt; "#" &lt;&lt; endl; int nBytes=string_to_llint(request_.substr(1,request_.size()-2)); cout &lt;&lt; "nBytes=" &lt;&lt; nBytes &lt;&lt; endl; cout &lt;&lt; "size=" &lt;&lt; inputStreamBuffer_.size() &lt;&lt; endl; boost::asio::async_read( socket_, inputStreamBuffer_, boost::asio::transfer_at_least(nBytes), boost::bind( &amp;session::doReadBody, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred) ); } else { delete this; } } void doReadBody( const boost::system::error_code&amp; error, size_t bytes_transferred) { if (!error) { istream is(&amp;inputStreamBuffer_); vector&lt;char&gt; v(bytes_transferred); is.read(&amp;(v[0]),bytes_transferred); request_.append(v.begin(),v.end()); string response=cardIssueProcessor_.process(request_); cout &lt;&lt; "request=#" &lt;&lt; request_ &lt;&lt; "#" &lt;&lt; endl; cout &lt;&lt; "response=#" &lt;&lt; response &lt;&lt; "#" &lt;&lt; endl; request_.clear(); boost::asio::async_write( socket_, boost::asio::buffer(response, response.size()), boost::bind( &amp;session::doWriteResponse, this, boost::asio::placeholders::error) ); } else { delete this; } } </code></pre> <p>Now, the header is read. But reading the footer blocks. Apparently the entire message is read in the header call. When I do the second async_read() with boost::asio::transfer_at_least(nBytes), nBytes are already in inputStreamBuffer_, but I think the call doesn't check this?</p> <p>This is dump from the output:</p> <p>request_=#Z24,# nBytes=24 size=24</p> <p>What is the problem, or how can I workaround it. I am a boost newbie, so all help appreciated. Thank you.</p> <p>EDIT: I tried to check the buffer fullness, and don't make async_read() call for the body if it happens to be already read by previous call. It kind of works, but is it the right solution?</p> <pre><code>void doReadHeader( const boost::system::error_code&amp; error, size_t bytes_transferred) { if (!error) { istream is(&amp;inputStreamBuffer_); vector&lt;char&gt; v(bytes_transferred); is.read(&amp;(v[0]),bytes_transferred); request_.assign(v.begin(),v.end()); cout &lt;&lt; "request_=#" &lt;&lt; request_ &lt;&lt; "#" &lt;&lt; endl; int nBytes=string_to_llint(request_.substr(1,request_.size()-2)); cout &lt;&lt; "nBytes=" &lt;&lt; nBytes &lt;&lt; endl; cout &lt;&lt; "size=" &lt;&lt; inputStreamBuffer_.size() &lt;&lt; endl; size_t toReadBytes=nBytes-inputStreamBuffer_.size(); if (toReadBytes&gt;0) { boost::asio::async_read( socket_, inputStreamBuffer_, boost::asio::transfer_at_least(toReadBytes), boost::bind( &amp;session::doReadBody, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred) ); } else { doReadBody(error,nBytes); } } else { delete this; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload