¿Cuál es la mejor manera de implementar un latido en C ++ para verificar la conectividad del socket?

StackOverflow https://stackoverflow.com/questions/495922

  •  20-08-2019
  •  | 
  •  

Pregunta

Hola pandilla. Acabo de escribir un cliente y un servidor en C ++ usando sys / socket. Necesito manejar una situación en la que el cliente todavía está activo pero el servidor está inactivo. Una forma sugerida de hacer esto es usar un latido para afirmar periódicamente la conectividad. Y si no hay ninguno para intentar volver a conectar cada X segundos durante el período de tiempo Y, y luego agotar el tiempo de espera.

¿Es esto " latido del corazón " Cuál es la mejor manera de verificar la conectividad?

El socket que estoy usando podría tener información, ¿hay alguna forma de verificar que haya una conexión sin alterar el búfer?

¿Fue útil?

Solución

Si usa sockets TCP a través de una red IP, puede usar la función keepalive del protocolo TCP, que periódicamente verificará el socket para asegurarse de que el otro extremo todavía esté allí. (Esto también tiene la ventaja de mantener válido el registro de reenvío de su socket en cualquier enrutador NAT entre su cliente y su servidor).

Aquí hay una descripción general de TCP keepalive que describe algunas de las razones por las que usted podría querer usar TCP keepalive; este CÓMO específico de Linux describe cómo configurar su socket para usar TCP keepalive en tiempo de ejecución.

Parece que puede habilitar TCP keepalive en los sockets de Windows configurando SIO_KEEPALIVE_VALS usando función WSAIoctl () .

Si usa sockets UDP sobre IP, necesitará construir su propio latido en su protocolo.

Otros consejos

Sí, este latido es la mejor manera. Tendrá que incorporarlo al protocolo que el servidor y el cliente usan para comunicarse.

La solución más simple es hacer que el cliente envíe datos periódicamente y que el servidor cierre la conexión si no ha recibido ningún dato del cliente en un período de tiempo determinado. Esto funciona perfectamente para protocolos de consulta / respuesta donde el cliente envía consultas y el servidor envía respuestas.

Por ejemplo, puede usar el siguiente esquema:

  1. El servidor responde a cada consulta. Si el servidor no recibe una consulta durante dos minutos, cierra la conexión.

  2. El cliente envía consultas y mantiene la conexión abierta después de cada una.

  3. Si el cliente no ha enviado una consulta durante un minuto, envía un " ¿estás ahí " consulta. El servidor responde con & Quot; yes I am & Quot ;. Esto restablece el temporizador de dos minutos del servidor y confirma al cliente que la conexión aún está disponible.

Puede ser más simple hacer que el cliente cierre la conexión si no ha necesitado enviar una consulta en el último minuto. Dado que todas las operaciones son iniciadas por el cliente, siempre puede abrir una nueva conexión si necesita realizar una nueva operación. Eso lo reduce a esto:

  1. El servidor cierra la conexión si no ha recibido una consulta en dos minutos.

  2. El cliente cierra la conexión si no ha necesitado enviar una consulta en un minuto.

Sin embargo, esto no asegura al cliente que el servidor está presente y listo para aceptar una consulta en todo momento. Si necesita esta capacidad, deberá implementar un & Quot; ¿está allí & Quot; & "; sí, soy &"; consulta / respuesta en su protocolo.

Si el otro lado se ha ido (es decir, el proceso ha muerto, la máquina se ha averiado, etc.), intentar recibir datos desde el zócalo debería provocar un error. Sin embargo, si el otro lado simplemente se cuelga, el zócalo permanecerá abierto. En este caso, tener un latido es útil. Asegúrese de que cualquier protocolo que esté utilizando (encima de TCP) sea compatible con algún tipo de & Quot; do-nothing & Quot; solicitud o paquete: cada lado puede usar esto para realizar un seguimiento de la última vez que recibió algo del otro lado, y luego puede cerrar la conexión si transcurre demasiado tiempo entre paquetes.

Tenga en cuenta que esto supone que está utilizando TCP / IP. Si está utilizando UDP, entonces esa es otra caldera de pescado, ya que no tiene conexión.

Ok, no sé qué hace su programa ni nada, así que tal vez esto no sea factible, pero le sugiero que evite tratar de mantener siempre abierto el socket. Solo debe estar abierto cuando lo esté usando, y debe estar cerrado cuando no lo esté.

Si está entre lecturas y escrituras esperando la entrada del usuario, cierre el socket. Diseñe su protocolo de cliente / servidor (suponiendo que lo esté haciendo a mano y no esté utilizando ningún protocolo estándar como http y / o SOAP) para manejar esto.

Los sockets producirán un error si se corta la conexión; escriba su programa de manera que no pierda ninguna información en caso de tal error durante una escritura en el socket y que no obtenga ninguna información en caso de error durante una lectura desde el socket. La transaccionalidad y la atomicidad deben incluirse en el protocolo de su cliente / servidor (nuevamente, suponiendo que lo esté diseñando usted mismo).

tal vez esto lo ayude, TCP Keepalive HOWTO o esto SO_SOCKET

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