Reputation: 964
Introduction
I'm studying c++
and boost/asio
to implement a distributed system, so I need create an asynchronous tcp server.
The server works like an echo-server but you need make the request first (for example, send text through the socket) and the server just responds the pi number.
Tcp-connection class used in Main-server class
class tcp_connection
: public boost::enable_shared_from_this <tcp_connection> {
public:
typedef boost::shared_ptr<tcp_connection> pointer;
static pointer create(boost::asio::io_service &io_service){
return pointer(new tcp_connection(io_service));
}
tcp::socket &socket(){
return socket_;
}
void start(){
for(;;){
boost::asio::async_read(socket_, boost::asio::buffer(buffer_),
boost::bind(&tcp_connection::handle_read, shared_from_this(),
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)
);
buffer_ = "Pi: 3.1415\n\0";
boost::asio::async_write(socket_, boost::asio::buffer(buffer_),
boost::bind(&tcp_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
}
private:
tcp_connection(boost::asio::io_service &io_service)
: socket_(io_service){
}
void handle_write(const boost::system::error_code& /*error*/,
size_t /*bytes_transferred*/){
}
void handle_read(){
}
//attr
tcp::socket socket_;
std::string buffer_;
};
Problem
I've read some tutorials and many questions in stackoverflow. And I can't understand why I've this bug: error: ‘void (tcp_connection::*)()’ is not a class, struct, or union type
.
I found the error source in this line: boost::asio::async_read(...)
. If I remove that line, server works fine, but I need understand the async_read
functionality to implement complex systems later.
Upvotes: 0
Views: 332
Reputation: 16256
Your async_read
expects a handler - a function that will be called when something is read from the socket. This handler should have a specific signature. In your case it should be something like
void handle_read(boost::system::error_code const& ec, size_t bytes_transferred)
just because you use it as
boost::bind(&tcp_connection::handle_read, shared_from_this(),
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)
So you bind tcp_connection::handle_read
with this
(kind of) (the first implicit argument to any non-static method) and error code and number of bytes transferred, so expected signature is void handle_read(boost::system::error_code const& ec, size_t bytes_transferred)
. Maybe you need to learn more about how binding
works: http://www.boost.org/doc/libs/1_58_0/libs/bind/doc/html/bind.html
As a bonus:
your
for (;;)
{
//read
// write
}
is synchronous approach. You need something different if you want to use async one. The main idea is to chain them so your read takes a handler and the handler async writes response taking a write handler and the write handler starts another async read, and so looped.
Upvotes: 1