2010-10-13 14 views
13

otro en la saga de mí mismo frente a Boost.Asio ...Boost.Asio: Operación cancelada en async_read

que tienen un simple cliente y el servidor asíncrono que utilizan async_write y async_read para comunicarse. El cliente puede escribir correctamente bytes en el socket, pero el servidor nunca los ve; mi manejador de lectura en el servidor falla con "Operación cancelada".

Me inclino a creer que esto puede ser un problema de tiempo con el cliente a escribir los datos después de que el servidor ha tratado de leerlo y fallidos, pero yo habría pensado que los datos estarían esperando en la toma de todas formas (a menos que el socket se haya cerrado mientras tanto).

Para probar esto simplemente re-encontré con la operación de lectura en el controlador de errores, es decir

read_handler() 
{ 
    if (!error) { 
     /* bytes read */ 
    } else { 
     async_read(socket, buffer, read_handler) 
    } 
} 

Pero todo esto me fue un error de segmentación en pthread_mutex_lock través de una llamada a async_receive.

¿Alguien podría dirigirme hacia la información relevante (o, mejor aún, decirme exactamente qué estoy haciendo mal;))?

ACTUALIZACIÓN: El servidor y el cliente se basa en el ejemplo de servidor de chat en la documentación Asio, con el cliente y el servidor, tanto en ejecución en el marco del mismo proceso (este podría ser un problema Pensando un poco más que ambos utilizan el? mismo io_service ...); ambos asincrónicos y usando Boost 1.44.0. Estoy trabajando en OS X pero también es reproducible en Linux.

ACTUALIZACIÓN II: Mi corazonada era correcta y si el servidor y el cliente reciben objetos io_service separados, async_read ve los bytes en el socket. Esto todavía da una segfault en boost::asio::detail::kqueue_reactor::post_immediate_completion que parece provenir del io_service.run(). Antes de ir más allá, ¿está utilizando objetos separados io_service el enfoque correcto?

+0

Qué plataforma está ejecutando en? –

+0

La plataforma es OSX y Linux; ambos exhiben el mismo problema. – kfb

+0

¡Creo que necesitamos ver un poco más de tu código para tener la oportunidad de adivinar lo que has hecho mal! También ayudaría saber algo sobre su configuración: ¿el cliente y el servidor se ejecutan en la misma máquina o en máquinas diferentes, por ejemplo? ¿Ambos están escritos usando boost :: asio? ¿Qué versión de Boost estás usando (asio ha cambiado bastante recientemente)? – dajames

Respuesta

25

El funcionamiento cancelado (código de error de operation_aborted) se envía cuando el socket está closed o cancelado.

Lo más probable es que su conexión esté de alguna manera fuera del alcance.

Tal como me sucedió a mí, olvidó adjuntar async_handlers a un puntero shared_from_this(). Es decir Usted debe a conectar sus controladores de la siguiente manera:

async_read(m_socket, 
      boost::asio::buffer((void*)m_buffer, m_header_size), 
      boost::bind(&TcpConnection::handleRead, 
      shared_from_this(), 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 

Y NO así:

async_read(m_socket, 
      boost::asio::buffer((void*)m_buffer, m_header_size), 
      boost::bind(&TcpConnection::handleRead, 
      this, //<- This will go out of scope and the socket will be closed 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
+2

Gracias, tuve un bloqueo en una región totalmente diferente, pero también con un mensaje de error 'Operación cancelada '. ¡Y fue que un 'esto' salió fuera del alcance! Afortunadamente encontré su respuesta después de depurarla durante horas ... – Chris

+0

esa es la mejor respuesta de todas. error completamente extraño. diagnóstico absolutamente perfecto. – Alex

+0

y por qué exactamente la conexión está fuera de alcance, cuando esto se pasa? – bryanph

Cuestiones relacionadas