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:
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:
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:
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:
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:
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