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?

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top