Boost Asio async_read не перестает читать?
Так,
Я играл с функциями и сокетами 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 ответа
Дикое предположение: вы проверяете error
в handle_read
? Если сокет находится в состоянии ошибки по какой-то причине, я предполагаю, что вложенный вызов async_read
сделан из handle_read
будет немедленно "завершено", что приведет к немедленному вызову handle_read
У меня была такая же проблема. В моем случае я читал в 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";
}
}
Я нашел это решение, читая это
После сдачи этих двух строк все идет хорошо.