Boost Asio async_read no deja de leer?
-
08-07-2019 - |
Pregunta
Entonces,
He estado jugando con las funciones y sockets de Boost asio (específicamente la lectura / escritura asíncrona). Ahora, pensé que boost :: asio :: async_read
solo llamaba al controlador cuando entraba un nuevo buffer desde la conexión de red ... sin embargo, no deja de leer el mismo buffer y por lo tanto sigue llamando el manejador He podido mitigarlo comprobando la cantidad de bytes transferidos, sin embargo, básicamente está en un ciclo de espera ocupada que desperdicia los ciclos de la CPU.
Esto es lo que tengo:
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));
}
};
Algunas cosas se cortan, pero básicamente se crea una nueva conexión y luego se llama a start ()
. ¿Hay algo que me falta para que el método handle_read
no se llame continuamente?
Solución
Una suposición descabellada: ¿verifica error
en handle_read
? Si el socket está en un estado de error por alguna razón, supongo que la llamada anidada a async_read
hecha desde handle_read
se completará de inmediato y dará como resultado una llamada inmediata a handle_read
Otros consejos
Estaba teniendo el mismo problema. En mi caso, estaba leyendo en un std :: vector como este:
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)
);
Tengo un vector adaptativo para aceptar un número de bytes variante
std::vector<unsigned char>* message;
message = new std::vector<unsigned char> (sizePacket);
Cuando recibía el primer paquete, todo iba bien, pero después del primero, nunca deja de desbloquear handle_reader sin datos.
Mi solución fue eliminar mi vector y asignar espacio nuevamente después de procesarlo:
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";
}
}
Encontré esta solución leyendo esto
Después de poner estas dos líneas, todo va bien.