Así que he creado una clase de socket que usa la biblioteca boost :: asio para realizar lecturas y escrituras asíncronas. Funciona, pero tengo algunas preguntas.boost :: Asio operaciones y recursos asíncronos
Aquí está un ejemplo de código básica:
class Socket
{
public:
void doRead()
{
m_sock->async_receive_from(boost::asio::buffer(m_recvBuffer), m_from, boost::bind(&Socket::handleRecv, this, boost::asio::placeholders::error(), boost::asio::placeholders::bytes_transferred()));
}
void handleRecv(boost::system::error_code e, int bytes)
{
if (e.value() || !bytes)
{
handle_error();
return;
}
//do something with data read
do_something(m_recvBuffer);
doRead(); //read another packet
}
protected:
boost::array<char, 1024> m_recvBuffer;
boost::asio::ip::udp::endpoint m_from;
};
Parece que el programa leerá un paquete, manejarlo, a continuación, se preparan para leer otro. Sencillo. Pero, ¿y si configuro un grupo de subprocesos? ¿Debería la siguiente llamada a doRead()
ser antes o después de manejar los datos leídos? Parece que si se pone antes de do_something()
, el programa puede comenzar inmediatamente a leer otro paquete, y si se coloca después, el hilo está vinculado haciendo lo que do_something()
hace, lo que posiblemente podría tomar un tiempo. Si pongo el doRead()
antes del manejo, ¿significa eso que los datos en m_readBuffer
podrían cambiar mientras lo estoy manejando?
Además, si estoy usando async_send_to()
, ¿debo copiar los datos que se enviarán a un búfer temporal, porque el envío real podría no ocurrir hasta que los datos hayan caído fuera del alcance? es decir
void send()
{
char data[] = {1, 2, 3, 4, 5};
m_sock->async_send_to(boost::buffer(&data[0], 5), someEndpoint, someHandler);
} //"data" gets deallocated, but the write might not have happened yet!
Además, cuando la toma está cerrado, el handleRecv será llamada con lo que indica que se interrumpió un error. Si hago
Socket* mySocket = new Socket()...
...
mySocket->close();
delete mySocket;
podría causar un error, porque hay una posibilidad de que mySocket
se eliminarán antes de handleRecv()
obtiene la llamada/terminado?
+1 para una buena pregunta, pero en el futuro sugiero dividirla en preguntas separadas en Stackoverflow. –