Comment déterminer correctement si mon client est toujours connecté au serveur avec des sockets C?

J’ai un client connecté à un serveur via des sockets C Berkeley. J’essaie régulièrement de vérifier si la connexion est toujours valide en appelant recv () sur le socket avec MSG_DONTWAIT et MSG_PEEK. Cependant, je constate que cet appel renvoie EAGAIN à la fois lorsque la connexion est interrompue (par exemple, après la fermeture de l’interface de la connexion) et lorsqu’il n’y a tout simplement aucune donnée à lire. Par conséquent, il n’ya aucun moyen pour moi de distinguer si la connexion est toujours valide ou n’utilise pas cette méthode.

Voici ma fonction:

/* return 1 if still connected, 0 otherwise */ int still_connected() { int nbytes_recvd = 0; char buf[2]; int err; nbytes_recvd = recv(fd,buf,sizeof(buf),MSG_PEEK|MSG_DONTWAIT); err = errno; if ( nbytes_recvd == 0 ) { return 0; } else if ( nbytes_recvd  0 or EAGAIN or EWOULDBLOCK */ /* but I get EAGAIN even if the connection is down because I shut down the interface */ return 1; } 

Comment puis-je vérifier avec précision si la connexion est toujours valide?

Du sharepoint vue de l’un des deux points de terminaison d’une connexion TCP, il n’existe aucune différence entre un homologue disparu et un homologue toujours présent mais qui n’envoie simplement aucune donnée. Vous ne pouvez pas distinguer ces situations avec recv() ou avec une autre méthode.

Le seul moyen de détecter si un homologue est hors service, s’est réinitialisé, a disparu ou est devenu inaccessible est d’envoyer des données et de voir ce qui se passe. Il y a deux options:

  • Activer les keepalives TCP ( SO_KEEPALIVE ). Cela fera que TCP envoie un paquet keepalive de temps en temps et attend un ACK de ACK de l’homologue. Si l’homologue échoue à ACK , vous pouvez alors apprendre que la connexion a été rompue.
  • Envoyez des données d’application réelles (ou un message keepalive au niveau de l’application) selon la planification de votre choix. De même, si l’homologue ne répond pas à ces données (ou si vous obtenez une erreur de socket après l’avoir envoyée), vous pouvez apprendre que la connexion a été interrompue.