Bonjour.
Dans le cadre d'un développement d'une application orienté réseau basé sur les sockets, je me retrouve confronté à un problème assez génant.
En effet, je travaille avec un moteur basé sur les sockets en mode asynchrone, mais dès que je déconnecte le socket de l'application hote, il m'est impossible de relancer une écoute "proprement".
Voici ma méthode asynchrone de déconnexion :
et l'endroit où le code plante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 public void Disconnect() { if (reader.socket != null) { if(reader.socket.Connected) reader.socket.BeginDisconnect(true, new AsyncCallback(DisconnectCallBack), reader.socket); } } private void DisconnectCallBack(IAsyncResult result) { (result.AsyncState as Socket).EndDisconnect(result); if (Disconnected != null) Disconnected(this, EventArgs.Empty); }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 public void WaitConnexion(IPEndPoint localEP) { if (localEP.Port != XXXX) { MessageBox.Show("Le port doit être XXXX"); return; } if (reader.socket != null) if (reader.socket.Connected) { MessageBox.Show("Vous êtes déjà connecté", "Conflit de connexion", MessageBoxButton.OK, MessageBoxImage.Exclamation); return; } LocalEndPoint = localEP; // on bind le socket avec le endpoint local, et on le met en attente de connexion asynchrone reader.socket.Bind(localEP); // plantage ici lors d'un bind après le //EndDisconnect, soit pour cause d'argument invalide, soit pour cause de //port déja utilisé reader.socket.Listen(1); reader.socket.BeginAccept(new AsyncCallback(WaitConnexionCallBack), reader.socket); }
reader est un objet qui contient le buffer, une constante sur la taille du buffer et le socket utilisé dans l'intégralité du moteur.
La seule méthode que j'ai trouvé et qui marche correctement est la suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 //ajouté dans le DisconnectCallBack reader.socket.Close(); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();Mais passer par le garbage collector pour nettoyer les informations du socket de la mémoire, c'est un peu goret a mon goût et j'aimerais savoir si il n'y a pas une VRAIE méthode pour résoudre ce problème.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 // ajouté dans le WaitConnexion : reader.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
J'ai déjà essayé ceci, sans succès :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 reader.socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true)
En espérant avoir été clair et que quelqu'un pourra m'éclairer ...
Cordialement,
KiTe
Partager