Socket 2.0 c# serveur multiclient Déconnexion reconnexion

Résolu
sdess Messages postés 18 Date d'inscription mardi 1 juin 2004 Statut Membre Dernière intervention 15 avril 2010 - 30 janv. 2009 à 10:54
sdess Messages postés 18 Date d'inscription mardi 1 juin 2004 Statut Membre Dernière intervention 15 avril 2010 - 31 janv. 2009 à 14:32
Bonjour,

J'ai deux problèmes concernant une application client/serveur avec un mode de communication Assynchrone, framework 2.0, en c#:

1°) concernant les multi-clients. Je ne parviens pas à connecter 2 clients sur le même serveur. Unitairement, je parviens à me connecter au serveur, mais dès que j'en ai un client de connecté, l'autre n'y arrive pas (peut importe celui qui est connecté en premier).

2°) Quand je déconnecte mon client, je n'arrive pas à le reconnecter. même après une attente de 5-10 minutes.

Voici ma classe de base client :

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;



namespace Outils
{
 public class BaseClient : ClientServeur
 {
  private ManualResetEvent _connectDone = new ManualResetEvent(false);



  public virtual Socket Start (string adresseIP, int port)
  {
   IPAddress remoteIPAddress = System.Net.IPAddress.Parse (adresseIP);
   return Start (remoteIPAddress, port);
  }



  public virtual Socket Start (IPAddress adresseIP, int port)
  {
   Socket client = null;
   try
   {
    IPEndPoint remoteEndPoint = new System.Net.IPEndPoint (adresseIP, port);
    client = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    client.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
    client.BeginConnect (remoteEndPoint, new AsyncCallback (ConnexionEffectuee), client);
    _connectDone.WaitOne (TimeSpan.FromSeconds(6),false );
    if (client != null && client.Connected)
     DemarerEcouteServeur (client);
    else
     client = null;
   }
   catch (SocketException)
   {
    Deconnection (client);
   }
   catch (ObjectDisposedException)
   {
    Deconnection (client);
   }
   
   return client;
  }



  private void ConnexionEffectuee (IAsyncResult resultat)
  {
   Socket client = null;
   try
   {
    client = (Socket)resultat.AsyncState;
    client.EndConnect (resultat);
    _connectDone.Set ();
   }
   catch (SocketException)
   {
    Deconnection (client);
   }
   catch (ObjectDisposedException)
   {
    Deconnection (client);
   }
  }




  private void DemarerEcouteServeur(Socket client)
  {
   try
   {
    EtatSocketReseau state = new EtatSocketReseau();
    state.SocketCourante = client;
    client.BeginReceive(state.Buffer,0,ClientServeur.BUFFER_SIZE,SocketFlags.None,new AsyncCallback(Reception),state);
   }
   catch (SocketException)
   {
    Deconnection (client);
   }
   catch (ObjectDisposedException)
   {
    Deconnection (client);
   }
  } 
 }
}





Voici ma classe de base Serveur :

using System;
using System.Text;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Net;
using System.Xml.Serialization;



namespace Outils
{
 [Serializable]
 public class BaseServeur : ClientServeur
 {
  private int _port;
  private int _maxConnexion = 10;
  private List<EtatSocketReseau> _listeClients = new List<EtatSocketReseau> ();



  [XmlIgnore]
  public List<EtatSocketReseau> ListeClients
  {
   get { return _listeClients; }
   set { _listeClients = value; }
  }



  [XmlIgnore]
  public int MaxConnexion
  {
   get { return _maxConnexion; }
   set { _maxConnexion = value; }
  }



  [XmlIgnore]
  public int Port
  {
   get { return _port; }
   set { _port = value; }
  }



  public virtual void Start ()
  {
   Socket listener = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
   IPEndPoint ipLocal = new System.Net.IPEndPoint (IPAddress.Any, _port);
   listener.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
   listener.Bind (ipLocal);
   listener.Listen (_maxConnexion);



   listener.BeginAccept (new AsyncCallback (AcceptationConnexion), listener);
  }



  public virtual void Stop ()
  {
   foreach (EtatSocketReseau state in _listeClients)
   {
    Deconnection (state.SocketCourante);
   }
   _listeClients = new List<EtatSocketReseau> ();
  }



  private void AcceptationConnexion (IAsyncResult resultat)
  {
   Socket listener = null;
   Socket client = null;
   try
   {
    listener = (Socket)resultat.AsyncState;
    client = listener.EndAccept (resultat);
    if (client != null && client.Connected)
     System.Console.WriteLine(String.Format( "Connexion du client : {0}",client.RemoteEndPoint.ToString()));



    EtatSocketReseau state = new EtatSocketReseau ();
    state.SocketCourante = client;
    _listeClients.Add (state);
    client.BeginReceive (state.Buffer, 0, ClientServeur.BUFFER_SIZE, SocketFlags.None, new AsyncCallback (Reception), state);
   }
   catch (SocketException)
   {
    Deconnection (client);
    Deconnection (listener);
   }
   catch (ObjectDisposedException)
   {
    Deconnection (client);
    Deconnection (listener);
   }
  }
 }
}





Voici la classe commune :

using System;
using System.Text;
using System.Net.Sockets;
using System.Threading;



namespace Outils
{

 public class ClientServeur
 {



  public static readonly int BUFFER_SIZE = 128;
  private ManualResetEvent _sendDone = new ManualResetEvent (false);



  public bool SendCommande (Socket listener, string message)
  {
   if (listener == null)
    return false;
   if (!listener.Connected)
    return false;
   try
   {
    byte[] byteData = Encoding.ASCII.GetBytes (message);



    listener.BeginSend (byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback (EndSend), listener);
    _sendDone.WaitOne (TimeSpan.FromSeconds(60),false);



    if (message != String.Empty)
     SendCommande (listener, string.Empty);
   }
   catch (SocketException)
   {
    Deconnection (listener);
   }
   catch (ObjectDisposedException)
   {
    Deconnection (listener);
   }
   return true;
  }



  private void EndSend (IAsyncResult resultat)
  {
   Socket listener = null;
   listener = (Socket)resultat.AsyncState;
   int quantiteOctet = listener.EndSend (resultat);
   _sendDone.Set ();
  }



  internal void Reception (IAsyncResult resultat)
  {
   Socket client = null;
   try
   {
    EtatSocketReseau state = (EtatSocketReseau)resultat.AsyncState;
    client = state.SocketCourante;
    int quantiteOctets = client.EndReceive (resultat);



    if (quantiteOctets > 0)
    {
     state.Sb.Append (Encoding.ASCII.GetString (state.Buffer, 0, quantiteOctets));
     client.BeginReceive (state.Buffer, 0, ClientServeur.BUFFER_SIZE, SocketFlags.None, new AsyncCallback (Reception), state);
     if (quantiteOctets <  ClientServeur.BUFFER_SIZE)
      TraitementReponse (state);
    }
    else
    {
     if (state.Sb.Length > 1)
     {
      TraitementReponse (state);
     }
    }
   }
   catch (SocketException)
   {
    Deconnection (client);
   }
   catch (ObjectDisposedException)
   {
    Deconnection (client);
   }
  }



  public virtual void Deconnection (Socket socket)
  {
   if (socket != null && socket.Connected)
   {
    socket.Shutdown (SocketShutdown.Both);
    socket.Close ();
   }
   socket = null;
  }
 }
}








Merci d'avance aux bonnes âmes qui pourront m'aider à régler ces deux problèmes.



<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /??>
 




Je m’excuse pour la longueur de ce post.


Steeve

4 réponses

crougni77 Messages postés 28 Date d'inscription dimanche 24 août 2003 Statut Membre Dernière intervention 28 septembre 2009
30 janv. 2009 à 14:49
Salut Sdess ;)

je n'ai pas testé ton code, mais à première vue il ne te manquerais qu'une boucle sur ton listener.BeginAccept() de ta classe BaserServeur.

Car là effectivement ton serveur ne pourra géré qu'une seule connexion client.

il faudrait ajouter également un ManualResetEvent dans ta classe BaseServeur, pour gérer les connexion Clients.

private ManualResetEvent newClient = new ManualResetEvent(false);

private ManualResetEvent newClient = new ManualResetEvent(false);

...

while(true)
{
    newClient.Reset();
    listener.BeginAccept (new AsyncCallback (AcceptationConnexion), listener);
    newClient.WaitOne();
}

Et ajouter un newClient.Set() dans ta méthode AcceptationConnexion...

j'espère que cela pourra résoudre tes problèmes ;)

CrougniMan
3
crougni77 Messages postés 28 Date d'inscription dimanche 24 août 2003 Statut Membre Dernière intervention 28 septembre 2009
30 janv. 2009 à 19:33
pour ton second problème, je pense qu'il est complétement lié au premier, ton serveur n'accepte qu'UNE seule connexion.

Donc si tu te déco, tu ne pourra plus te reconnecter.

Si tu résou ton premier problème, le second sera automatiquement réglé

CrougniMan
3
sdess Messages postés 18 Date d'inscription mardi 1 juin 2004 Statut Membre Dernière intervention 15 avril 2010
30 janv. 2009 à 14:58
Merci pour ta réponse, je vais tester.

Sinon, Concernant mon problème n° 2 de déconnection / Reconnection, tu n'aurais pas une idée ?

Cordialement,

Steeve
0
sdess Messages postés 18 Date d'inscription mardi 1 juin 2004 Statut Membre Dernière intervention 15 avril 2010
31 janv. 2009 à 14:32
Un grand merci CrougniMan.

Cela fonctionne impeccablement.

Steeve
0
Rejoignez-nous