2009-05-04 11 views
5

¿Cuál es la forma más fácil de verificar si un socket está cerrado en el lado remoto de la conexión? socket::is_open() devuelve verdadero incluso si está cerrado en el lado remoto (estoy usando boost::asio::ip::tcp::socket).¿Cómo comprobar si el socket está cerrado en Boost.Asio?

Podría intentar leer de la transmisión y ver si tiene éxito, pero tendría que cambiar la lógica de mi programa para que funcione de esta manera (no quiero que se extraigan datos de la transmisión en el punto del cheque).

+0

¿Por qué necesita saber si la conexión remota se ha cerrado? – outis

+0

Además, ¿está utilizando un protocolo de aplicación de su propio diseño o un protocolo estándar? – outis

+0

Estoy escribiendo un programa de chat básico, y debo notificar al usuario que la otra persona cerró la aplicación. Tengo mi propio protocolo y ya he agregado un mensaje de "Salir". El único inconveniente es que no se envía si la aplicación se mata/se bloquea/etc. – Hali

Respuesta

4

Si la conexión ha sido limpiamente cerrada por el par, debe obtener un EOF mientras lee. De lo contrario, generalmente hago un ping para averiguar si la conexión está realmente viva.

+1

... y necesito leer para obtener el EOF. Supongo que no hay forma de evitarlo. Gracias! – Hali

7

¿Hay una función de aumento de inspección disponible? La mayoría de las implementaciones de sockets tienen una forma de leer datos sin eliminarlos de la cola, por lo que puede volver a leerlos más tarde. Esto parece satisfacer tus necesidades.

Después de echar un vistazo rápidamente a los documentos de asio, no pude encontrar exactamente lo que esperaba, pero eso no significa que no esté allí.

Sugiero this para empezar.

+0

Sí, tienes razón. Puede pasar un indicador al método "recibir" que le dice que no elimine los datos. Estaba usando el método "read_some", que no tiene este argumento de indicador. ¡Gracias por mencionarlo! – Hali

+0

supongamos que ha configurado el socket y la respuesta, entonces puede configurar una secuencia, p. std :: istream myhttpstream (y presponse); y luego puede usar la función std :: istream :: peek(). –

+0

Hago esto: received = socket(). Receive (boost :: asio :: buffer (buf), tcp :: socket :: message_peek); –

1

Creo que, en general, una vez que abre un socket, debe comenzar a leerlo inmediatamente y nunca dejar de hacerlo. De esta manera, puede hacer que su servidor o cliente sea compatible con los protocolos síncronos y asíncronos. En el momento en que el cliente cierra la conexión, en el momento en que la lectura le diga esto.

0

El uso de error_code permite verificar si el cliente está conectado o no. Si la conexión es exitosa, error_code error.value() devolverá 0, de lo contrario devolverá otro valor. También puede verificar el mensaje() desde el código de error.

7

Solo compruebe el error boost::asio::error::eof en su controlador async_receive. Significa que la conexión ha sido cerrada. Esa es la única forma correcta de hacer esto.

Cuestiones relacionadas