Reputation: 964
Introduction
I'm trying create a thread to receive data from socket.
Code
void ClientTcp::read_handler(tcp::socket s){
for(;;){
char buffer[max_buffr];
boost::system::error_code error;
size_t length = s.read_some(boost::asio::buffer(buffer), error);
if (error == boost::asio::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw boost::system::system_error(error); // Some other error.
buffer[length] = '\0';
std::cout << "-> " << buffer << std::endl;
}
}
void ClientTcp::run(){
tcp::socket s(io_service_);
tcp::resolver resolver(io_service_);
boost::asio::connect(s, resolver.resolve({ip_, port_}));
boost::thread read_th(read_handler, std::move(s));
std::string message;
for(;;){
std::cin >> message;
boost::asio::write(s, boost::asio::buffer(message, message.size()));
}
read_th.join();
}
Problem
This line boost::thread read_th(read_handler, std::move(s));
has a bug that i can't understand.
Error
no matching function for call to boost::thread::thread(<unresolved overloaded function type,
std::remove_reference<boost::asio::basic_stream_socket<boost::asio::ip::tcp>&>::type)
Main Question How I launch a thread from class method ?
Upvotes: 2
Views: 720
Reputation: 15075
It seems that boost::thread
constructor is unable to perform "perfect forwarding" of its arguments (and you can't use bind
for the reason described in the comments to @sehe answer).
However, being a part of C++11, std::thread
does forward the arguments correctly, so the following compiles:
#include <boost/asio.hpp>
#include <thread>
using namespace boost::asio;
void read_handler(ip::tcp::socket && s)
{
}
int main()
{
io_service io;
ip::tcp::socket s(io);
std::thread read_th(read_handler, std::move(s));
}
Note that if read_handler
is a non-static member function (like in your question), you should bind it with the object instance: std::thread(&ClientTcp::read_handler, this, std::move(s));
(Of course, the object lifespan should be taken into account, as well as the design considerations raised by @sehe.)
Upvotes: 0
Reputation: 392999
To answer the wrong question: You'd use boost::bind
boost::thread read_th(boost::bind(&ClientTcp::read_handler, this, std::move(s)));
But you certainly do not want to do that. Use a thread per asynchronous operation doesn't work at all.
Boost let's you achieve asynchrony without the need for additional threads. Just use the async_*
functions instead of the functions you
re using:
async_read_some
async_write
.Don't forget to run io_service::run()
.
Upvotes: 2