I am trying to use a c++11 lambda with boost::asio::async_read_until as follows:
void TCPSession::readData()
{
auto self(shared_from_this());
boost::asio::async_read_until(socket_, buffer_, "\r\n",
[this, self](const boost::system::error_code& ec, std::size_t length)
{
log()->debug("received %lu bytes && ec: %d", length, ec); //use boost::log for compile time checking
std::ostringstream ss;
ss << &buffer_;
log()->debug("Received data: %s",ss.str());
if (!ec){
log()->debug("We never get here!");
[... process data ...]
readData();
}
}
);
}
What I observe is that that length=0. The ec is set appropriately to the boost EOF code.
I also see the data when I convert the member (ie buffer_) to a string.
Any suggestions on getting the length initialized would be helpful.
An example output:
2014-10-09 14:47:56.968142 [tcp-session] debug: received 0 bytes && ec: asio.misc:2
2014-10-09 14:47:56.974593 [tcp-session] debug: Received data: test7.2.3.5 0.18722307655 2014-10-09 14:47:55.343591
test7.2.3.5 -0.0691607464759 2014-10-09 14:47:55.343837
test7.2.3.5 0.151471040421 2014-10-09 14:47:55.344017
test7.2.3.5 0.172789025585 2014-10-09 14:47:55.344211
test7.2.3.5 0.0409326066787 2014-10-09 14:47:55.344406
Try
printf("received %lu bytes", length);
// ...
printf("Received data: %s", ss.str().c_str());
Or better yet,
std::cout << "received " << length << " bytes\n";
// ...
std::cout << "Received data: " << ss.str();
%d
is not the right format for size_t. (This is why C++ was invented. Some decades ago)
Note: Your compiler would have told you most of this if you enabled warnings ( -Wall -Wextra -pedantic
)
Now, the docs say that
// The number of bytes in the streambuf's get
// area up to and including the delimiter.
// 0 if an error occurred.
So, since the ec is EOF, this explains that length
is also 0.
The below sample prints: Live On Coliru
received 0 bytes, ec: End of file
Received data: hello world
byebye
(Assuming that the responding server sends "hello world\\n");
#include <boost/asio.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
#include <cstring>
#include <iostream>
struct TCPSession : boost::enable_shared_from_this<TCPSession>
{
void readData();
TCPSession(boost::asio::io_service& svc) : socket_(svc) {
using boost::asio::ip::tcp;
socket_.connect(tcp::endpoint { {}, 6767 });
}
boost::asio::ip::tcp::socket socket_;
boost::asio::streambuf buffer_;
};
void TCPSession::readData()
{
auto self(shared_from_this());
boost::asio::async_read_until(socket_, buffer_, "\r\n",
[this, self](const boost::system::error_code& ec, std::size_t length)
{
std::cout << "received " << length << " bytes, ec: " << ec.message() << "\n";
std::ostringstream ss;
ss << &buffer_;
std::cout << "Received data: " << ss.str();
if (!ec){
std::cout << "We never get here!";
//[... process data ...]
readData();
}
std::cout << "byebye\n";
}
);
}
int main()
{
boost::asio::io_service svc;
auto sess = boost::make_shared<TCPSession>(svc);
sess->readData();
svc.run();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.