I'm trying to asynchrosouly read from a pipe using boost::asio::async_read, but it reads zero bytes everytime. However, I can succussfuly read from the pipe using the read function(unistd.h);
here's my code:
auto io = make_shared<boost::asio::io_service>();
auto work = make_shared<boost::asio::io_service::work>(*io);
int read_end = atoi(argv[0]);
auto pipe_read = make_shared<boost::asio::readable_pipe>(*io, read_end);
string message;
boost::thread_group worker_threads;
for(int i = 0; i < 1; i )
{
// I'm calling io->run() inside the worker thread.
worker_threads.create_thread(boost::bind(&workerThread, io));
}
// The handler function gets the number of bytes read, which is always zero.
boost::asio::async_read(*pipe_read, boost::asio::buffer(message, 5), boost::bind(&handler, _1, _2));
cout << message << endl;
work.reset();
worker_threads.join_all();
return 0;
Any help would be much appreciated.
CodePudding user response:
Given a
std::string message;
then asio::buffer(message)
has size 0 (because the string is empty).
The overload taking a size asio::buffer(message, 5)
can only limit the size, but doesn't provide it. So it is still size 0.
This explains your symptoms. Instead,
std::string message(5, '\0');
auto b = asio::buffer(message);
Or, alternatively,
std::string message;
message.resize(1024); // cue Bill Gates miss-quote
auto b = asio::buffer(message, 5);
Or even use dynamic buffers:
std::string message;
auto b = asio::dynamic_buffer(message/*, 5*/);
Live Demo
Showing a modernized version also fixing the various bugs I remarked:
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <iostream>
namespace asio = boost::asio;
void handler(boost::system::error_code ec, size_t xfr) {
std::cout << "Received " << xfr << " bytes (" << ec.message() << ")\n";
}
int main(int argc, char** argv) {
asio::thread_pool ioc(1); // or more threads
assert(argc > 1);
int read_end = atoi(argv[1]);
auto pipe_read = make_shared<boost::asio::readable_pipe>(ioc, read_end);
std::string message(5, '\0');
boost::asio::async_read(*pipe_read, asio::buffer(message), &handler);
ioc.join();
std::cout << message << std::endl;
}
Prints
./a.out 0 <<< "HELLO WORLD"
Received 5 bytes (Success)
HELLO