GNU/Linux >> Tutoriels Linux >  >> Linux

Comment utiliser correctement l'option SO_KEEPALIVE pour détecter que le client à l'autre bout est en panne ?

Pour modifier le nombre de sondes ou les intervalles de sonde, vous écrivez des valeurs dans le système de fichiers /proc comme

 echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time
 echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl
 echo 20 > /proc/sys/net/ipv4/tcp_keepalive_probes

Notez que ces valeurs sont globales pour tous les sockets activés keepalive sur le système. Vous pouvez également remplacer ces paramètres socket par socket lorsque vous définissez setsockopt, voir la section 4.2 du document que vous avez lié.

Vous ne pouvez pas "vérifier" l'état du socket depuis l'espace utilisateur avec keepalive. Au lieu de cela, le noyau est simplement plus agressif pour forcer l'extrémité distante à reconnaître les paquets et déterminer si le socket a mal tourné. Lorsque vous essayez d'écrire sur le socket, vous obtenez un SIGPIPE si keepalive a déterminé que l'extrémité distante est en panne.


Vous obtiendrez le même résultat si vous activez SO_KEEPALIVE, comme si vous n'activiez pas SO_KEEPALIVE - généralement, vous trouverez le socket prêt et obtiendrez une erreur lorsque vous le lirez.

Vous pouvez définir le délai d'attente keepalive socket par socket sous Linux (il peut s'agir d'une fonctionnalité spécifique à Linux). Je recommanderais ceci plutôt que de modifier le paramètre à l'échelle du système. Voir la page de manuel de tcp pour plus d'informations.

Enfin, si votre client est un navigateur Web, il est fort probable qu'il fermera le socket assez rapidement de toute façon - la plupart d'entre eux ne maintiendront les connexions keepalive (HTTP 1.1) ouvertes que pendant un temps relativement court (30 s, 1 min, etc.). Bien sûr, si la machine cliente a disparu ou si le réseau est en panne (ce que SO_KEEPALIVE est vraiment utile pour détecter), alors elle ne pourra pas fermer activement le socket.


Comme déjà discuté, SO_KEEPALIVE rend le noyau plus agressif pour vérifier continuellement la connexion même lorsque vous ne faites rien, mais pas modifier ou améliorer la manière dont les informations vous sont fournies. Vous saurez quand vous essayez réellement de faire quelque chose (par exemple "écrire"), et vous le saurez tout de suite puisque le noyau signale maintenant simplement l'état d'un indicateur précédemment défini, plutôt que d'avoir à attendre quelques secondes (ou beaucoup plus dans certains cas) pour que l'activité du réseau échoue. La même logique de code que vous aviez pour gérer la condition "l'autre côté est parti de manière inattendue" sera toujours utilisée ; ce qui change, c'est le timing (pas la méthode).

Pratiquement tous les programmes de sockets "pratiques" fournissent d'une manière ou d'une autre non -bloquer l'accès aux sockets pendant la phase de données (peut-être avec select()/poll(), ou peut-être avec fcntl()/O_NONBLOCK/EINPROGRESS&EWOULDBLOCK, ou si votre noyau le supporte peut-être avec MSG_DONTWAIT). En supposant que cela soit déjà fait pour d'autres raisons, il est trivial (parfois ne nécessitant aucun code) de découvrir immédiatement en plus une perte de connexion. Mais si la phase de données ne le fait pas fournissent déjà d'une manière ou d'une autre un accès non bloquant aux sockets, vous ne serez pas informé de la perte de connexion avant la prochaine fois que vous essaierez de faire quelque chose.

(Une connexion de socket TCP sans une sorte de comportement non bloquant pendant la phase de données est notoirement fragile, comme si le mauvais paquet rencontrait un problème de réseau, il est très facile pour le programme de "se bloquer" indéfiniment, et il n'y a pas grand-chose que vous peut faire à ce sujet.)


Linux
  1. Comment utiliser la commande Linux grep

  2. Comment utiliser la commande history sous Linux

  3. Comment ajouter une nouvelle ligne à la fin d'un fichier ?

  4. Comment utiliser la commande "screen" sous Linux

  5. LINUX :comment détecter que le téléchargement de fichier ftp est terminé

Comment utiliser la commande top sous Linux

Comment utiliser la commande Linux Ping

Comment utiliser la commande nmap

Comment utiliser la commande fd sur le système Linux

Comment utiliser la commande wget sous Linux ?

Comment utiliser la commande xargs sous Linux ?