Socket connectée [Résolu]

Signaler
Messages postés
27
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
28 juin 2008
-
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
-
Bonjour!
Pourriez-vous m'indiquer une manière de vérifier qu'une socket est toujours active, que le client à l'autre bout n'a pas fermé l'application?
J'ai essayé la méthode avec Poll et Available==0 mais ça ne donne rien, et j'ai lu que la propriété Connected ne s'actualisait pas au cours du temps, alors pourriez-vous me donner une méthode fiable?

Merci d'avance

Immerczeck

11 réponses

Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Modérateur
Dernière intervention
30 octobre 2008
50
Bonjour,
Je suis très embété parce que je viens de faire un rapide essai, et ca marche.

Le code dans mon thread :


<HR>
lock(
this.clientsList.SyncRoot)
{

foreach (
Client client
in
this.clientsList)
{

if (client.Socket.Poll(10,
SelectMode.SelectRead) && client.Socket.Available == 0)

Console.WriteLine(
string.Format(
"client {0} deconnecté", client.IDClient));
}
}

<HR>

Par contre c'est sur que je mettrais pas ce code dans le thread qui gere les message, mais dans un thread dedié a la detection de deconnexion sauvage..
Et dans ce thread, je ne ferais pas de boucle active ( while(true) ), mais je le déclencherais plutot via un timer, toutes les X secondes.


Mx
MVP C#
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
90
Ou en mettant une pause, ainsi que la gestion de ThreadAbortException.

Sinon tu peux aussi prévoir dans ton protocole un timeout au bout duquel tu considères que ton client est parti si tu n'as pas reçu de données.
Ou définir un message auquel le client doit répondre pour signaler qu'il est toujours là. :-)

/*
coq
MVP Visual C#
*/
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Modérateur
Dernière intervention
30 octobre 2008
50
L'idée du Timer en plus clair :


<HR>


System.Threading.Timer timer =
new System.Threading.
Timer(
new
TimerCallback(ListenForDeconnection),
null, 0, 10000);
[...]

private
void ListenForDeconnection(
object state)
{

foreach (idclient client in ArrayList.Synchronized(clients))
{
if(client.sock.Poll(10, SelectMode.SelectRead) && client.sock.Available==0)
{
....
}
}

}

<HR>

Mx
MVP C#
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Modérateur
Dernière intervention
30 octobre 2008
50
Salut,

Pourtant c'est une bonne technique (la bonne technique ? )
Qu'entends-tu par "ca ne donne rien" ?

Une autre technique, dans le cadre d'un client qui se deconnecte "proprement" (pas de plantage), serait que le client envoie un message au serveur pour le prevenir qu'il se deconnecte.

Sinon, je ne connais pas d'autre méthode que celle du Poll.


Mx
MVP C#
Messages postés
27
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
28 juin 2008

ben ça ne donne rien dans le sens où ça ne réagit pas lorsque le client se déconnecte. Voici un bout du code :

while(true)
{ [...]
foreach (idclient client in ArrayList.Synchronized(clients))
{
if(client.sock.Poll(10, SelectMode.SelectRead) && client.sock.Available==0)
{
richTextBox1.Text+= "Le client "+ client.nick+" s'est déconnecté\r";
listBox1.Items.Remove(client.nick);
ArrayList.Synchronized(clients).Remove(client);
}[...]
}
}

Pitetre me suis-je trompé quelque part...
Sinon j'avais pensé à la solution du message envoyé par le client à déconnexion, mais comme tu l'as dit, dans le cas d'un plantage... c'est plutôt gênant de garder une socket déconnectée...
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Modérateur
Dernière intervention
30 octobre 2008
50
Ca m'a pourtant bien l'air d'etre ca...
Essayons de diagnostiquer...
Est-ce que le thread dans lequel se trouve ta boucle tourne bien ? As tu essayé de debugger en pas a pas, pour voir les valeurs qu'il pouvait te donner ? (genre ton arraylist vide)
Es-tu sur que le client avec lequel tu testes est bien deconnecté (ca peut paraitre bete comme question, mais bon, parfois on pense qu'on a fermé le client, mais le process tourne encore en fond parce qu'un thread n'a pas sa propriété IsBackground a true)


Mx
MVP C#
Messages postés
27
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
28 juin 2008

Oui, le client est bien déconnecté, je n'ai pas mis ISBackground à true, c'est trop brutal, j'ai arrangé l'évènement Closing de la form. Je teste en réseau local, j'ai donc tous les moyens de vérifier. Le thread tourne bien, puisque c'est le même qui s'occupe de la gestion des messages (là peut-être que ça vient de là, j'aurais peut-être dû les séparer).
L'arrayList n'est pas vide puis que j'ai en permanence une listbox qui m'affiche tous les client.nick.

Immerczeck
Messages postés
3466
Date d'inscription
lundi 16 octobre 2000
Statut
Modérateur
Dernière intervention
30 octobre 2008
50
J'aurais aussi fait ca, (et d'ailleurs, j'ai toujours fait ca jusque maintenant). Mais j'ai recemment entendu d'un prof que c'etait pas terrible de faire une boucle dans un Thread avec une pause dedans, alors j'ai voulu donner une autre possibilité, en me disant qu'elle etait peut-etre meilleure que la mienne.
Maintenant, si tu ferais comme ca aussi coq, c'est que ca doit pas etre une si mauvaise solution que ca



Mx
MVP C#
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
90
Je ne suis pas très pointu en threading, mais c'est juste que l'utilisation d'un timer pour lancer le thread à intervalle réguliers me paraissait un peu bizarre.
Je vais essayer de trouver des infos sur la question.

/*
coq
MVP Visual C#
*/
Messages postés
27
Date d'inscription
jeudi 2 septembre 2004
Statut
Membre
Dernière intervention
28 juin 2008

merci de vos réponses!
juste une question, pourquoi une boucle while(true) n'est pas une bonne solution?
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
90
En général on essaie d'éviter les boucles infinies, mais je pense qu'ici Mx parlait plus du principe de passer par le thread en général plutôt que de l'utilisation de la boucle infinie en particulier.
Pour ma part je ne pense pas que ce soit forcément une très mauvaise idée, pour autant que son utilisation soit "justifiée' et qu'on prévoit de quoi en sortir proprement. (et d'y prévoir une temporisation si nécessaire afin de ne pas non plus consommer inutilement du temps)
Mais il est clair que dans ton cas il vaut mieux passer par la méthode proposée par Mx :-)

/*
coq
MVP Visual C#
*/