Comment pouvez-vous vérifier si un socket réseau (System.Net.Sockets.Socket) est toujours connecté si l'autre hôte ne vous envoie pas de paquet lors de sa déconnexion (par exemple parce qu'il s'est déconnecté de façon disgracieuse)?
Réponses
Trop de publicités?Comme la Programmation Héros répondit Socket.Connected
ne peut pas être utilisé dans cette situation. Vous avez besoin d'un sondage de connexion à chaque fois pour voir si la connexion est toujours active. C'est le code que j'ai utilisé:
bool SocketConnected(Socket s)
{
bool part1 = s.Poll(1000, SelectMode.SelectRead);
bool part2 = (s.Available == 0);
if (part1 && part2)
return false;
else
return true;
}
Il fonctionne comme ceci:
-
s.Poll
retourne true si- la connexion est fermée, reset, terminés ou en cours (ce qui signifie pas de connexion active)
- la connexion est active et il y a des données disponibles pour la lecture
-
s.Available
renvoie le nombre d'octets disponibles pour la lecture - si les deux sont vrais:
- il n'y a pas de données disponible à la lecture, si la connexion n'est pas active
Comme l'a écrit zendar , il est agréable d'utiliser les Socket.Poll
et Socket.Available
, mais vous devez prendre en considération que le socket n'a peut-être pas été initialisé en premier lieu. Il s'agit du dernier élément d'information (je crois) et il est fourni par la propriété Socket.Connected
. La version révisée de la méthode ressemblerait à ceci:
static bool IsSocketConnected(Socket s)
{
return !((s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)) || !s.Connected);
/* The long, but simpler-to-understand version:
bool part1 = s.Poll(1000, SelectMode.SelectRead);
bool part2 = (s.Available == 0);
if ((part1 && part2 ) || !s.Connected)
return false;
else
return true;
*/
}
L' Socket.Connected
de la propriété vous permet de savoir si un socket pense qu'il est connecté. Il reflète en fait l'état de la dernière envoyer/recevoir de l'opération effectuée sur le socket.
Si le support a été fermé par vos propres actions (débarrasser de la douille, l'appel de méthodes à déconnecter), Socket.Connected
sera de retour false
. Si le support a été déconnecté par d'autres moyens, la propriété sera de retour true
jusqu'à la prochaine tentative d'envoyer ou de recevoir de l'information, à quel point soit une SocketException
ou ObjectDisposedException
sera levée.
Vous pouvez vérifier la propriété après l'exception a eu lieu, mais il n'est pas fiable avant.
La meilleure façon est simplement que votre client envoie un PING toutes les X secondes, et que le serveur suppose qu'il est déconnecté après n'en avoir reçu aucun pendant un certain temps.
J'ai rencontré le même problème que vous lors de l'utilisation de sockets, et c'était la seule façon de le faire. La propriété socket.connected n'a jamais été correcte.
En fin de compte cependant, je suis passé à l'utilisation de WCF car il était beaucoup plus fiable que les sockets.
Utilisez Socket.Connected
Propriété.