What's the meaning of boost::asio::placeholders::bytes_transferred
What is the meaning of boost::asio::placeholders::bytes_transferred
in async_read_until()
? In the callback function it returns smaller value, than streambuf.size()
. streambuf
was clear before the callback. To sum up,...bytes_transferred
is not the actual number of bytes went through the socket, but less. Do I have misunderstood all of this, or what?
EDIT: I read the following protocol from a socket:
Y43,72,0,,91009802000000603=0000000000000000000
"Y43,"
- is the header.
"Y"
- is message type.
"43"
- additional bytes to read
","
- delimiter. The header is the until the first "," encountered.
My code is for reading is like:
void handle_write(const boost::system::error_code& error,
size_t bytes_transferred)
{
if (!error)
{
boost::asio::async_read_until(
socket_,
inputStreamBuffer_,
',',
boost::bind(
&client::handle_read1, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
else
{
std::cout << "Write failed: " << error << "\n";
}
}
void handle_read1(const boost::system::error_code& error,
size_t bytes_transferred)
{
cout << "bytes_transferred=" << bytes_transferred << endl;
if (!error)
{
cout << "0 size=" << inputStreamBuffer_.size() << endl;
istream is(&inputStreamBuffer_);
char c[1000];
is.read(c,bytes_transferred);
c[bytes_transferred]=0;
for (int i=0;i<bytes_transferred;++i)
{
cout << dec << "c[" << i << "]=" << c[i] << " hex=" << hex << static_cast<int>(c[i]) << "#" << endl;
}
}
else
{
std::cout << "Read failed: " << error << "\n";
}
}
For stream sent from the other side:
Y43,71,0,,91009802000000595=0000000000000000000
Some times, I read this:
bytes_transferred=4
0 size=47
c[0]=Y hex=59#
c[1]=4 hex=34#
c[2]=3 hex=33#
c[3]=, hex=2c#
For stream sent from the other side:
Y43,72,0,,9开发者_Python百科1009802000000603=0000000000000000000
But other times, I read this:
bytes_transferred=7
0 size=47
c[0]= hex=0#
c[1]= hex=0#
c[2]= hex=0#
c[3]= hex=0#
c[4]=7 hex=37#
c[5]=2 hex=32#
c[6]=, hex=2c#
The socket is secured with SSL, and the client and server apps are slightly modified examples from boost_asio/example/ssl/* .
In the second example I loose the entire header :(
There's four overloads of the function but let's just assume the first one is used. If you look at the documentation, then you'll see that bytes_transferred
is the amount of bytes to and including the delimiter specified.
And furthermore:
After a successful async_read_until operation, the streambuf may contain additional data beyond the delimiter. An application will typically leave that data in the streambuf for a subsequent async_read_until operation to examine.
Resolved. I was passing std::string
object to boost::asio::buffer()
, instead of std::string.c_str()
when sending the reply from the server.
As the docs suggest, you should be able to ignore anything beyond bytes_transferred
and just call async_read_until
again.
However if you happen to be using the all-new SSL implementation in ASIO 1.5.3 (which is not officially part of boost yet), you might run into the same issue I did (for which I submitted a patch):
http://comments.gmane.org/gmane.comp.lib.boost.asio.user/4803
It doesn't look like you're using the new version or running into the same problem, but it's something to be aware of if you hit some limitations and are tempted by the advantages of the new implementation:
The new implementation compiles faster, shows substantially improved performance, and supports custom memory allocation and handler invocation. It includes new API features such as certificate verification callbacks and has improved error reporting. The new implementation is source-compatible with the old for most uses.
精彩评论