IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Problème serveur multithread


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2010
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2010
    Messages : 100
    Par défaut Problème serveur multithread
    Bonjour tout le monde,

    J'avais ouvert un topic qui portait sur la création d'un serveur multithread en C#, donc je ne sais pas si je devais continuer dans ce topic ou pas. Si oui désolé d'avoir créé un nouveau topic.

    Donc voici en gros la situation: J'ai un serveur qui tourne sur un pc et une application mobile vient se connecter dessus pour pouvoir y échanger des données.

    Voici mon problème, la communication se passe bien et tout mais lorsque le client quitte la session et que je veux me reconnecter, il me lance une exception me disant que la connexion a été fermée. Peut-être (ou certainement) que j'ai mal codé les deux parties mais si vous pouviez me mettre sur la voie, ce serait fort sympathique

    Le code pour le serveur tournant sur la machine :

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    class ServeurReseauAsync
        {
            #region variables globales
     
            public static byte[] buf = new byte[1024];
            public static AutoResetEvent serveurArrete = new AutoResetEvent(false);
            public static IPAddress adresseServeur;
            public static int port;
            public static FormGAPScanServer parent;
     
            public static String protocole;
     
            #endregion
     
            [STAThread]
            public static void main()
            {
                try
                {
                    Socket socketEc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    socketEc.Bind(new IPEndPoint(adresseServeur, port));
                    socketEc.Listen(100);
                    IAsyncResult ar = socketEc.BeginAccept(new AsyncCallback(AcceptRealise), socketEc);
                    ar.AsyncWaitHandle.WaitOne();
     
                    serveurArrete.WaitOne();
                }
                catch (SocketException ex)
                {
                    MessageBox.Show("Vérifier que vous êtes connecté à un réseau sans fil !", "Avertissement",MessageBoxButtons.OK,MessageBoxIcon.Error,MessageBoxDefaultButton.Button1);
                }
     
            }
     
            static void AcceptRealise(IAsyncResult ar)
            {
                Socket socketC = (Socket)ar.AsyncState;
                Socket sockC = socketC.EndAccept(ar);
     
                IPEndPoint ep = (IPEndPoint)sockC.RemoteEndPoint;
     
                Boolean fin = false;
     
                try
                {
     
                    while (!fin)
                    {
                        IAsyncResult e = sockC.BeginReceive(buf, 0, buf.Length, 0, new AsyncCallback(ReceptionRealisee), sockC);
     
                        e.AsyncWaitHandle.WaitOne();
     
                        String msgCli = ASCIIEncoding.Default.GetString(buf, 0, buf.Length);
     
                        MessageBox.Show("Message : " + msgCli);
     
                        if (msgCli.CompareTo("2$#") == 0)
                        {
                            fin = true;
                        }
                    }
                }
                catch (SocketException ex)
                {
                    MessageBox.Show("Perte de connexion hôte.", "Avertissement", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
     
                }
     
                sockC.Shutdown(SocketShutdown.Both);
                sockC.Close();
     
                //serveurArrete.Set();
            }
     
            static void ReceptionRealisee(IAsyncResult ar)
            {
                Socket socketServ = (Socket)ar.AsyncState;
     
                int n = socketServ.EndReceive(ar);
                String msgClient = ASCIIEncoding.Default.GetString(buf, 0, n);
     
                String msgServeur = "nogapprotocol";
     
                #region analyse de la trame recue par le client
     
                List<String> maListe = DecoupeTrame.decoupage(msgClient);
     
                    protocole = maListe[0];
     
                    int IDProtocole = Int32.Parse(protocole);
     
     
                    #region protocole RECHERCHERARTICLE
     
                    if (IDProtocole == ProtocolGAP.RECHERCHEARTICLE)
                    {
                        String idArticle = maListe[1];
     
                        try
                        {
     
                            if (ConfigurationManager.AppSettings["cheminBDMercator"] == null)
                                throw new ExceptionPropertiesNotFound("Fichier de properties non disponible !");
                            else
                            {
                                String cheminMercator = ConfigurationManager.AppSettings["cheminBDMercator"];
     
                                ManipulationDBMercator manip = new ManipulationDBMercator(cheminMercator);
     
                                String responseRequete = manip.getStockDispoViaIDArticle(idArticle);
     
                                if (responseRequete == null)
                                {
                                    msgServeur = "null";
                                }
                                else
                                {
                                    msgServeur = responseRequete;
                                }
                            }
                        }
                        catch (ExceptionPropertiesNotFound ex)
                        {
     
                        }
                    }
     
                    #endregion
     
                    #region Protocole QUITTER
     
                    if (IDProtocole == ProtocolGAP.QUITTER)
                    {
     
                    }
     
                    #endregion
     
                #endregion
     
                byte[] tb = ASCIIEncoding.Default.GetBytes(msgServeur);
     
                IAsyncResult e = socketServ.BeginSend(tb, 0, tb.Length, 0, new AsyncCallback(EnvoiRealise), socketServ);
     
                e.AsyncWaitHandle.WaitOne();
            }
     
            static void EnvoiRealise(IAsyncResult ar)
            {
                Socket socketServ = (Socket)ar.AsyncState;
     
                int n = socketServ.EndSend(ar);
            }
     
        }
    Et le code du client mobile :

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    public class ClientAsyncTCP
        {
            #region variables globales
     
            private Socket socketC;
     
            #endregion
     
            #region constructeur
     
            public ClientAsyncTCP()
            {
     
            }
     
            #endregion
     
            public void connection()
            {
                socketC = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     
                IPAddress adresseServeur = IPAddress.Parse("169.254.221.190");
     
                try
                {
                    IAsyncResult ar = socketC.BeginConnect(new IPEndPoint(adresseServeur, 8001), new AsyncCallback(ConnexionRealisee), socketC);
     
                    socketC.EndConnect(ar);
                }
                catch (Exception ex)
                {
     
                }
            }
     
            public void ConnexionRealisee(IAsyncResult ar)
            {
                Socket sock = (Socket)ar.AsyncState;
            }
     
            public void EnvoyerRequete(String requete)
            {
                String msg = requete;
     
                byte[] tb = ASCIIEncoding.Default.GetBytes(msg);
     
                IAsyncResult ar = socketC.BeginSend(tb, 0, tb.Length, 0, new AsyncCallback(EnvoiRealise), socketC);
     
                socketC.EndSend(ar);
     
                if (msg.CompareTo("EOC") == 0)
                {
                    socketC.Shutdown(SocketShutdown.Both);
                    socketC.Close();
                    return;
                }
            }
     
            public String ReceptionRequete()
            {
                byte[] buf = new byte[1024];
     
                IAsyncResult ar = socketC.BeginReceive(buf, 0, buf.Length, 0, new AsyncCallback(ReceptionRealisee), socketC);
     
                socketC.EndReceive(ar);
     
                String msgServeur = ASCIIEncoding.Default.GetString(buf, 0, buf.Length);
     
                List<String> liste = DecoupeTrame.decoupage(msgServeur);
     
                if (liste[0].CompareTo("2") == 0)
                {
                    socketC.Shutdown(SocketShutdown.Both);
                    socketC.Close();
                    msgServeur = "quit";
                }
     
                return msgServeur;
            }
     
            public void EnvoiRealise(IAsyncResult ar)
            {
     
            }
     
            public void ReceptionRealisee(IAsyncResult ar)
            {
     
            }
        }
    Merci d'avance,

    Julien

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 114
    Par défaut
    Bonjour,

    tu dois appeler BeginAccept dans AcceptRealise pour continuer à accepter des connexions entrante.

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2010
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2010
    Messages : 100
    Par défaut
    Merci pour ta réponse,

    Donc si je fais ça, cela devrait fonctionner ?

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    static void AcceptRealise(IAsyncResult ar)
            {
                Socket socketC = (Socket)ar.AsyncState;
                Socket sockC = socketC.EndAccept(ar);
     
                IPEndPoint ep = (IPEndPoint)sockC.RemoteEndPoint;
     
                Boolean fin = false;
     
                try
                {
     
                    while (!fin)
                    {
    IAsyncResult ar = socketEc.BeginAccept(new AsyncCallback(AcceptRealise), socketEc);
     
                        IAsyncResult e = sockC.BeginReceive(buf, 0, buf.Length, 0, new AsyncCallback(ReceptionRealisee), sockC);
     
                        e.AsyncWaitHandle.WaitOne();
     
                        String msgCli = ASCIIEncoding.Default.GetString(buf, 0, buf.Length);
     
                        MessageBox.Show("Message : " + msgCli);
     
                        if (msgCli.CompareTo("2$#") == 0)
                        {
                            fin = true;
                        }
                    }
                }
                catch (SocketException ex)
                {
                    MessageBox.Show("Perte de connexion hôte.", "Avertissement", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
     
                }
     
                sockC.Shutdown(SocketShutdown.Both);
                sockC.Close();
     
                //serveurArrete.Set();
            }
    En fait je ne comprend pas bien le principe de beginAccept. Lors d'une connexion il va lancer un nouvelle instance de la méthode AcceptRealise ?

    Merci d'avance,

    Julien

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 114
    Par défaut
    Personnellement, je le mettrais plutôt juste après le EndAccept

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    static void AcceptRealise(IAsyncResult ar)
            {
                Socket socketC = (Socket)ar.AsyncState;
                Socket sockC = socketC.EndAccept(ar);
                IAsyncResult ar = socketEc.BeginAccept(new AsyncCallback(AcceptRealise), socketEc);
     
                IPEndPoint ep = (IPEndPoint)sockC.RemoteEndPoint;
     
                Boolean fin = false;
     
                try
                {
     
                    while (!fin)
                    {
                        IAsyncResult e = sockC.BeginReceive(buf, 0, buf.Length, 0, new AsyncCallback(ReceptionRealisee), sockC);
     
                        e.AsyncWaitHandle.WaitOne();
     
                        String msgCli = ASCIIEncoding.Default.GetString(buf, 0, buf.Length);
     
                        MessageBox.Show("Message : " + msgCli);
     
                        if (msgCli.CompareTo("2$#") == 0)
                        {
                            fin = true;
                        }
                    }
                }
                catch (SocketException ex)
                {
                    MessageBox.Show("Perte de connexion hôte.", "Avertissement", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
     
                }
     
                sockC.Shutdown(SocketShutdown.Both);
                sockC.Close();
     
                //serveurArrete.Set();
            }
    Pour ce qui est du principe de BeginAccept, j'ai peur de mal expliquer...

    Mais en gros, si tu utilise la méthode Accept, ton application va être mise en attente jusqu'à ce qu'une connexion entrante arrive.
    Quand tu utilise une méthode qui commence par Begin (comme BeginAccept), la partie responsable de l'attente est mise dans un autre thread pour ne pas bloquer l'exécution de ton programme puis appel la méthode qui lui est donnée en paramètre une fois que la partie bloquante est finie.

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2010
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2010
    Messages : 100
    Par défaut
    Merci pour tes explications,

    super ça a l'air de fonctionner en plaçant cette ligne de code à cet endroit

    Merci pour la solution Je suppose donc que s'il y a plusieurs clients simultanés, il n'y aura pas de problème, car je n'ai qu'un pda pour tester donc je ne saurais pas tester ...

    A part ça, je marque le topic en résolu

    Julien

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [QThread] [QTCPSocket] Problème pour la réalisation d'un serveur multithread
    Par birdyz53 dans le forum Multithreading
    Réponses: 0
    Dernier message: 27/04/2011, 14h58
  2. Réponses: 2
    Dernier message: 28/04/2010, 03h15
  3. Client Serveur multithread : problème
    Par cb-bk dans le forum Threads & Processus
    Réponses: 1
    Dernier message: 04/04/2009, 16h05
  4. Réponses: 1
    Dernier message: 27/10/2005, 11h14
  5. Problème serveur Posgresql : recuperation anciennes requêtes
    Par petitmoosse dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 04/12/2004, 18h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo