2012-03-29 35 views
6

Estoy usando Boost :: asio para implementar una aplicación cliente/servidor. El código de cliente a continuación se usa para conectarse al servidor remoto.Cómo verificar si una conexión de socket está activa en Boost :: asio?

try 
    { 
     boost::asio::io_service   m_io_service; 
     boost::asio::ip::tcp::socket m_socket(m_io_service); 
     boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 17); 
     m_socket.connect(endpoint); 
    } 
    catch (std::exception& e) 
    { 
     std::cerr << e.what() << std::endl; 
    } 

En el lado del cliente, quiero comprobar si la conexión es en vivo. La función "m_socket.is_open();" no funciona. Cuando el socket del servidor está cerrado, el "m_socket.is_open();" sigue siendo verdadero en el lado del cliente. ¿Hay alguna forma de verificar la conexión?

+1

Tuve una duda similar aquí: http://stackoverflow.com/q/1511129/174605 y hay una buena respuesta por joshperry – coelhudo

Respuesta

2

Debido a la limitación de la interfaz de socket subyacente, no hay forma de implementar la función como isConnected para verificar el estado de conexión TCP en el nivel de socket. Creo que hay una solución al respecto.

En mi implementación, guardo en caché un indicador de estado de conexión (bool m_IsConnected) en mi aplicación. Esta bandera se usa para designar el estado de la conexión. Supone que si no hay un error en el socket, la conexión TCP está activa.

La bandera se actualizará cada vez que utilice el zócalo. Si hay errores al enviar y leer datos, eso significa que la conexión está desconectada. Luego cambie la bandera correspondiente. Si la conexión TCP está inactiva durante mucho tiempo. Este indicador no refleja el estado real de la conexión TCP hasta que se usa el socket. Por ejemplo, el socket está inactivo durante mucho tiempo. Está desconectado debido a la mala red. En este caso, m_IsConnected sigue siendo cierto, ya que no recibimos ninguna devolución de llamada con respecto al evento de desconexión. Cuando intente enviar datos a través de este socket, habrá un error. Y ahora sabemos que la conexión está desconectada.

0

Esto es una limitación de la interfaz de socket subyacente (creo que ambos para Winsock/Bekerly). Podría inventar un mensaje específicamente para este propósito, que el servidor responda si está vivo. De lo contrario, si obtienes un tiempo de espera, significa que la conexión no funciona.

EDITAR: Como señaló Joachim, tratar de leer el zócalo podría ser una mejor manera.

+3

Intentar enviar a una conexión que se ha cerrado dará dar un error, incluso si fue un cierre limpio y apropiado. Tratar de _read_ desde el socket dará una mejor pista sobre cómo se cerró el socket (es decir, 'read' o' recv' devuelve cero para un cierre limpio o un error cuando hay un error). –

+0

Ah sí, tienes razón, yo Olvidé que podrías leerlo también. Actualizará la respuesta anterior. – Rolle

+0

La función gratuita boost :: asio :: read se puede usar para leer el socket. Creo que hay un efecto secundario si se usa la función de lectura para detectar el estado de la conexión. Leerá los datos de la secuencia de socket, que es lo que no quiero en una función de detección de estado. Además, si la conexión está activa, la función de lectura bloquea. – Jeffrey

Cuestiones relacionadas