Boost Asio async_read не перестает читать? - PullRequest
1 голос
/ 28 октября 2009

Итак,

Я играл с функциями и сокетами Boost asio (в частности, асинхронное чтение / запись). Теперь я подумал, что boost::asio::async_read вызывает обработчик только тогда, когда из сетевого подключения поступает новый буфер ... однако он не прекращает чтение того же самого буфера и поэтому продолжает вызывать обработчик. Я смог смягчить его, проверив количество переданных байтов, однако это в основном в цикле ожидания, тратящем циклы процессора.

Вот что у меня есть:

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));
    }
};

Некоторые вещи вырезаны, но в основном создается новое соединение, затем вызывается start(). Я что-то упускаю, чтобы метод handle_read не вызывался непрерывно?

Ответы [ 2 ]

6 голосов
/ 28 октября 2009

Дикая догадка: вы проверяете error в handle_read? Если по какой-либо причине сокет находится в состоянии ошибки, я предполагаю, что вложенный вызов async_read из handle_read немедленно "завершится", что приведет к немедленному вызову handle_read

0 голосов
/ 20 апреля 2012

У меня была такая же проблема. В моем случае я читал в std :: vector так:

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)
    );

У меня есть адаптивный вектор для принятия варианта с числом байтов

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

Когда я получал первый пакет, все шло нормально, но после первого никогда не прекращается разблокировка handle_reader без данных.

Мое решение состояло в том, чтобы удалить мой вектор и снова выделить место после его обработки:

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";
    }
}

Я нашел это решение, читающее это

После помещения этих двух строк все идет хорошо.

...