Question

So,

I've been playing around with the Boost asio functions and sockets (specifically the async read/write). Now, I thought that boost::asio::async_read only called the handler when a new buffer came in from the network connection... however it doesn't stop reading the same buffer and thus keeps calling the handler. I've been able to mitigate it by checking the number of bytes transferred, however it is basically in a busy-waiting loop wasting CPU cycles.

Here is what I have:

class tcp_connection : : public boost::enable_shared_from_this<tcp_connection> 
{
public:
    // other functions here

    void start()
    {
    boost::asio::async_read(socket_, boost::asio::buffer(buf, TERRAINPACKETSIZE),
        boost::bind(&tcp_connection::handle_read, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
    }

private:
    const unsigned int TERRAINPACKETSIZE = 128;
    char buf[TERRAINPACKETSIZE];


    void handle_read(const boost::system::error_code& error, size_t bytesT)
    {
        if (bytesT > 0)
        { 
             // Do the packet handling stuff here
        }

        boost::asio::async_read(socket_, boost::asio::buffer(buf, TERRAINPACKETSIZE),
        boost::bind(&tcp_connection::handle_read, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
    }
};

Some stuff is cut out, but basically a new connection gets created then start() is called. Is there something I'm missing so that the handle_read method doesn't get continuously called?

Was it helpful?

Solution

A wild guess: Do you check error in handle_read? If the socket is in an error state for some reason, I guess that the nested call to async_read made from handle_read will immediately "complete", resulting in an immediate call to handle_read

OTHER TIPS

I was having the same problem. In my case, I was reading into a std::vector like this:

boost::asio::async_read(socket_,
st::asio::buffer(*message,message->size()),
            boost::bind(
              &ActiveSocketServerSession::handleFixLengthRead,
              shared_from_this(),
              boost::asio::placeholders::error,
              boost::asio::placeholders::bytes_transferred)
    );

I have an adaptative vector for accept a variant number of bytes

    std::vector<unsigned char>* message;
message = new std::vector<unsigned char> (sizePacket);

When I was receiving the first packet all was going fine, but after the first, never stops unlocking handle_reader with no data.

My solution was to delete my vector and alloc space again after processing it:

void ActiveSocketServerSession::handleFixLengthRead(    const         boost::system::error_code& error,
                                                    std::size_t bytes_transferred){

    --> processing your data (save to another site)
--> delete message;
--> message = new std::vector<unsigned char> (sizePacket);

//starting to read again
boost::asio::async_read(socket_,
                boost::asio::buffer(*message,message->size()),
            boost::bind(
              &ActiveSocketServerSession::handleFixLengthRead,
              shared_from_this(),
              boost::asio::placeholders::error,
              boost::asio::placeholders::bytes_transferred)
);

    }else{
        logMessage.str("");
        logMessage << "Error handling data id: "<<getId()<< "from port";
    }
}

I found this solution reading this

After putting these two lines all goes fine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top