Quel est le meilleur moyen d'implémenter une pulsation en C ++ pour vérifier la connectivité de socket?

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

  •  20-08-2019
  •  | 
  •  

Question

Hey gang. Je viens d'écrire un client et un serveur en C ++ en utilisant sys / socket. Je dois gérer une situation dans laquelle le client est toujours actif mais le serveur est en panne. Une méthode suggérée consiste à utiliser une pulsation pour affirmer périodiquement la connectivité. Et s’il n’ya personne pour essayer de se reconnecter toutes les X secondes pendant une période de temps, puis pour expirer.

S'agit-il de & "battements de coeur &"; le meilleur moyen de vérifier la connectivité?

Le socket que j'utilise peut contenir des informations, existe-t-il un moyen de vérifier qu'il existe une connexion sans perturber le tampon?

Était-ce utile?

La solution

Si vous utilisez des sockets TCP sur un réseau IP, vous pouvez utiliser la fonction keepalive du protocole TCP, qui vérifie périodiquement le socket pour s’assurer que l’autre extrémité est toujours là. (Cela présente également l’avantage de garder l’enregistrement de transfert de votre socket valide dans tous les routeurs NAT entre votre client et votre serveur.)

Voici un aperçu de la maintenance de TCP , qui décrit certaines des raisons pour lesquelles vous: voudra peut-être utiliser TCP keepalive; ce HOWTO spécifique à Linux explique comment configurer votre socket de manière à utiliser TCP keepalive. au moment de l'exécution.

Il semble que vous pouvez activer TCP keepalive dans les sockets Windows en définissant SIO_KEEPALIVE_VALS à l'aide de fonction WSAIoctl () .

Si vous utilisez des sockets UDP sur IP, vous devez créer votre propre rythme cardiaque dans votre protocole.

Autres conseils

Oui, ce battement de coeur est le meilleur moyen. Vous devrez l'intégrer au protocole utilisé par le serveur et le client pour communiquer.

La solution la plus simple consiste à faire en sorte que le client envoie périodiquement des données et que le serveur ferme la connexion s’il n’a reçu aucune donnée du client au cours d’une période donnée. Cela fonctionne parfaitement pour les protocoles de requête / réponse où le client envoie des requêtes et le serveur envoie des réponses.

Par exemple, vous pouvez utiliser le schéma suivant:

  1. Le serveur répond à chaque requête. Si le serveur ne reçoit pas de requête pendant deux minutes, il ferme la connexion.

  2. Le client envoie des requêtes et maintient la connexion ouverte après chacune d'entre elles.

  3. Si le client n'a pas envoyé de requête pendant une minute, il envoie un " êtes-vous là " question. Le serveur répond par & «Oui, je suis &». Cela réinitialise le compteur de minutes du serveur et confirme au client que la connexion est toujours disponible.

Il peut être plus simple de simplement fermer la connexion au client s'il n'a pas eu besoin d'envoyer une requête depuis une minute. Étant donné que toutes les opérations sont lancées par le client, il peut toujours simplement ouvrir une nouvelle connexion s'il doit effectuer une nouvelle opération. Cela le réduit à ceci:

  1. Le serveur ferme la connexion s'il n'a pas reçu de requête dans les deux minutes.

  2. Le client ferme la connexion s'il n'a pas besoin d'envoyer une requête en une minute.

Toutefois, cela ne garantit pas au client que le serveur est présent et prêt à accepter une requête à tout moment. Si vous avez besoin de cette fonctionnalité, vous devrez implémenter un & "Êtes-vous là-bas &"; " oui je suis " requête / réponse dans votre protocole.

Si l'autre partie est partie (c'est-à-dire que le processus est mort, que la machine est en panne, etc.), toute tentative de réception de données du socket entraînerait une erreur. Cependant, si l'autre côté est simplement suspendu, la prise restera ouverte. Dans ce cas, avoir un battement de coeur est utile. Assurez-vous que le protocole que vous utilisez (en plus du protocole TCP) prend en charge une sorte de & "Do-Nothing &"; request ou packet - chaque partie peut l'utiliser pour garder trace de la dernière fois où elle a reçu quelque chose de l'autre côté, puis peut fermer la connexion si trop de temps s'écoule entre les paquets.

Notez que cela suppose que vous utilisez TCP / IP. Si vous utilisez le protocole UDP, il s'agit d'une toute autre source de poisson, car il est sans connexion.

D'accord, je ne sais pas ce que votre programme fait ou quoi que ce soit, alors peut-être que ce n'est pas faisable, mais je vous suggère d'éviter d'essayer de toujours garder le socket ouvert. Il ne doit être ouvert que lorsque vous l'utilisez et doit être fermé lorsque vous ne l'utilisez pas.

Si vous êtes entre des lectures et des écritures en attente d'une entrée utilisateur, fermez le socket. Concevez votre protocole client / serveur (en supposant que vous le fassiez à la main et que vous n’utilisez aucun protocole standard tel que http et / ou SOAP) pour le gérer.

Les sockets se tromperont si la connexion est interrompue. écrivez votre programme de manière à ne perdre aucune information dans le cas d'une telle erreur lors d'une écriture sur le socket et que vous n'obteniez aucune information dans le cas d'une erreur lors d'une lecture à partir du socket. La transactionnalité et l'atomicité devraient être intégrées dans votre protocole client / serveur (encore une fois, à condition que vous le conceviez vous-même).

peut-être que cela vous aidera, HOWTO TCP Keepalive ou ce SO_SOCKET

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top