urb
urb

Reputation: 964

Problems with Async_Read function

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

Answers (1)

Andriy Tylychko
Andriy Tylychko

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

Related Questions