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

Windows Forms Discussion :

Probleme avec Show() et Socket


Sujet :

Windows Forms

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2007
    Messages : 46
    Par défaut Probleme avec Show() et Socket
    Bonjour,

    Je suis entrain de developper une application reseau et j'ai un big probleme qui m'empeche d'avancer et de terminer.
    Pour commencer, j'ai 1 programme identique qui tourne sur 2 machine, l'une se connecte en tant que serveur et l'autre en tant que Client.
    J'utilise pour ce faire et pour le reste, les sockets en reprenant le principe d'un mini tchat que j'ai vus a mon cours.

    Mon probleme, est que depuis le server j'envoi un string vers le client, ou vice versa. Le recepteur, lit ce qu'il a recu et en fonction de cela fait telle ou telle action.
    Pour bien des actions cela fonctionne sauf quelque une importante.

    Il n'arrive pas à afficher une Form, elle s'affiche mais son contenu reste Blanc et la fenêtre est bloquée.
    Pour l'afficher, j'utilise le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Carte crt = new Carte();
    crt.Show();
    J'ai tenté avec un ShowDialog, et cela fonctionne mieux, mais lors de l'appui sur l'un des boutons du form qui est prevu pour fermer la form avec simplement this.Close();
    Cela fait planter toute l'application avec le message envoyer / ne pas envoyer .

    Comment puis je faire pour pouvoir afficher correctement ma form sur mon recpeteur ? ou dirai que parce que l'envoyeur la ouverte, il ne peut pas l'ouvrir lui aussi.

    Merci d'avance
    Lionel

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Par défaut
    Bonsoir Lionel,

    dans les symptomes, ca m'a tout l'air d'etre un thread de form qui s'est terminé (form blanche qui ne repond plus). J'imagine que le recepteur ecoute sur un thread et ensuite utilise des traitements async pour traiter ce qu'il a recu.

    Bref, Show() n'est pas bloquant et si le thread appelant ne possede pas de pompe à message, tu vas passer par show() (le form s'affiche) et continuer (soit le thread se terminera, soit il repartira en ecoute (= bloqué)) la form ne repondra plus. Le fait de faire un ShowDialog() à la place arrange les choses puisque ce dernier incorpore sa propre pompe à message dans l'appel (ceci dit je ne sais pas pourquoi ca fait tout planter quand tu la fermes).

    En conclusion, gere ta form sur un thread dedié, que tu invoqueras si la procedure de reception le requiert (en la montrant, la cachant, la modifiant whatever).

    Par la meme, pourrais tu ne donner un peu de code, principalement montrant le cheminement depuis la reception du message sur le socket jusqu'à la procedure d'affichage (les grandes lignes, j'entends) ?

  3. #3
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2007
    Messages : 46
    Par défaut
    En conclusion, gere ta form sur un thread dedié, que tu invoqueras si la procedure de reception le requiert (en la montrant, la cachant, la modifiant whatever).
    Quand tu parle de Thread dedié, parle tu bien de faire ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public void AfficherForm()
    {
    Form fen = new Form();
    fen.Sho();
    }
    Sinon, voici un partie de mon code de mise en reseau (le tout faisant 450 lignes pour l'instant) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public void InitialiserReception(Socket sock)
            {
                AsyncCallback recep = new AsyncCallback(Reception);
                sock.BeginReceive(MonBuffer, 0, MonBuffer.Length, SocketFlags.None, recep, sock);
            }
    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
    public void Reception(IAsyncResult iar)
            {
                Socket bidule = (Socket)iar.AsyncState;
                if (bidule.Connected)
     
                    try
                    {
                        int nRec = bidule.EndReceive(iar);
                        if (nRec > 0)
                        {
                            Traitement(Encoding.Unicode.GetString(MonBuffer, 0, nRec));                        
                            InitialiserReception(bidule); //Réception du message suivant 
                            //MonBuffer = null;
                        }
                        else
                        {
                            bidule.Shutdown(SocketShutdown.Both);
                            bidule.Close();
                            //Server.BeginAccept(new AsyncCallback(DemandeConnexion), Server);
                        }
                    }
                    catch 
                    {
                        if (Principal.ServeurClient == true)
                        {
                            MessageBox.Show("Erreur pendant réception","Serveur");
                        }
                        else
                        {
                            MessageBox.Show("Erreur pendant réception", "Client");
                        }
                        InitialiserReception(bidule);
                    }
            }
    Mon traitement des données recues qui bloque :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     public void Traitement(string data)
            {
                if (data.Length > 0)
                {
                    if (data.Substring(0, 5) == "cais1")
                    {
                        Carte.afficher = true;
                        Carte.lecture = Principal.joueur1 + " à tiré la carte caisse de communauté : \n" + data.Substring(5);
                        Carte cart = new Carte();
                        cart.Show();
                    }
                } 
            }

  4. #4
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2007
    Messages : 46
    Par défaut
    Personne n'a de solution à me proposer ?
    Car il faut que je finisse mon projet pour demain soir.
    Et personnelement je n'ai pas d'idee.

    Pourrais ton me donner un exemple pour faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    En conclusion, gere ta form sur un thread dedié, que tu invoqueras si la procedure de reception le requiert (en la montrant, la cachant, la modifiant whatever).

    Merci d'avance.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par james_kirk Voir le message
    Quand tu parle de Thread dedié, parle tu bien de faire ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public void AfficherForm()
    {
    Form fen = new Form();
    fen.Sho();
    }
    Non, là tu as juste mis l'appel à Show dans une méthode... il faut créer un nouveau thread, c'est à dire un nouveau "fil d'exécution" qui s'éxécutera en parallèle.
    Mais dans ton cas ce n'est pas ça le problème je pense. Comme tu déclares la variable cart dans la fonction Traitement, elle cesse d'exister dès que la fonction se termine (ramassée par le garbage collector). Il faudrait que tu déclare et initialise cart à un plus haut niveau de ton programme (membre de classe par exemple).

  6. #6
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2007
    Messages : 46
    Par défaut
    Bonjour,

    Merci pour cette réponse, j'ai tenté de mettre ma déclaration de "cart" au début de ma classe Reseau qui contient Traitement et autre, mais j'ai un retour d'erreur a l'execution :
    System.StackOverflowException
    Qui survient au niveau de la déclaration de cart.
    Comment puis-je ressoudre cette erreur ?

    Sinon quand tu dis qu'il faut déclarer une Thread parrallele, cela signifie quoi ?
    Désolé je n'ai pas vus cela au cours, faudra que je me perfectionne plus tards ^^. Tu aurais un exemple ?


    EDIT : je viens de faire un petit test, et apparement, quand je fait appel a ma fenetre, il ne vas pas plus loin que .ShowDialog() et il attend a cet endroit tant que ma fenetre n'est pas fermée, c'est peut-etre une piste.
    Mais je ne vois pas trop quoi changer.

    Merci

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Par défaut
    Salut Lionel,

    desolé pour le retard, mais je vais essayer de te repondre.

    En fait, si tu fais un Show(), ton thread continue sa course, sort de la fonction d'affichage et part pour reinitialiser une autre ecoute. Cette derniere etant async, le thread ne s'arrete pas non plus, et doit continuer sa course, je ne sais ou, bref mauvaise solution.

    .ShowDialog semble arranger le probleme, car il permet, seul, d'avoir une boucle de message (essentiel pour une UI) incorporé, mais par contre, c'est bloquant (ce que tu as remarqué lors de ton test) faisant que la prochaine ecoute ne sera initialisée que lorsque tu fermeras la fenetre de dialogue ouverte, ce qui n'est pas, je pense, le but recherché.

    Bref, pour ton probleme, je verrais ca comme ca (on pourrait parler du design, mais c'est pour donner l'idée generale) :

    -un backend d'ecoute des sockets independant (en terme de threading) qui ecoute des messages, (voire meme les stocke) et leve un event pour signaler (à qui veut bien l'ecouter) qu'il y a des messages arrivés.

    - un frontend lui independant que l'on va rattacher à la classe d'ecoute (par une interface par exemple).

    Ce design te permet d'avoir une ecoute qui n'est plus liée sur son interface de presentation (seulement par une interface), et l'ecoute n'a plus à s'occuper d'affaire de show ou autre, il n'emet que des events. On pourrait par exemple faire comme ceci :

    Un listener (la pause simule l'ecoute) :
    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
        class SocketListener
        {
            public event EventHandler<NewMessageEventArgs> NewMessageReceived;
            public bool Continue { get; set; }
            static int i;
     
            public SocketListener()
            {
                Continue = true;
            }
     
            public void Idle()
            {
                while (Continue)
                {
                    Thread.Sleep(1000);
                    OnNewMessageReceived(new NewMessageEventArgs(i++.ToString()));
                }
            }
     
            private void OnNewMessageReceived(NewMessageEventArgs newMessageEventArgs)
            {
                if (NewMessageReceived != null)
                {
                    NewMessageReceived(this, newMessageEventArgs);
                }
            }
        }
    Une form (pour schematiser l'UI) :
    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
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
     
            public void NewMessage(object sender, NewMessageEventArgs e)
            {
                //Si la fenetre est construite
                if (this.IsHandleCreated)
                {
                    //Si l'invoke est necessaire
                    if (this.InvokeRequired)
                    {
                        this.Invoke(new EventHandler<NewMessageEventArgs>(NewMessage), new object[] { sender, e }); 
                        return;
                    }
                    //Ici on peut traiter le message recu dans l'UI
                }
            }
        }
     
        public class NewMessageEventArgs : EventArgs
        {
            public string S { get; set; }
            public NewMessageEventArgs(string s)
            {
                S = s;
            }
        }
    Et enfin la classe lancant tout le truc :
    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
        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
     
                SocketListener sL = null;
                Form1 f = new Form1();
     
                //On lance l'ecoute sur un thread dedié
                Thread t = new Thread(
                    delegate()
                    {
                        //On attache l'event et on lance l'ecoute
                        sL = new SocketListener();
                        sL.NewMessageReceived += f.NewMessage;
                        sL.Idle();
                    });
                t.Start();
     
                //Un callback pour fermer le Listener quand l'application se termine
                Application.ApplicationExit +=
                    delegate
                    {
                        sL.Continue = false;
                    };
                Application.Run(f);
     
            }
        }
    Voila, en gros l'idée etant une classe d'ecoute lancant des events si elle entend un truc (qu'il soit traité ou pas, c'est pas son probleme, on peut ameliorer ca, mais c'est un autre probleme), une UI qui recoit des notifications et les traite (si la classe d'ecoute est fermée, se termine ou autre, l'UI reste intacte et attendra), une classe de gestion (Program en l'occurence) qui lie et gere le tout.

    En esperant que cela t'aide, bon courage. =)

    edit*2 : (re)corrections ...

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Par défaut
    Je n'avais pas vu qu'apparement, tu apprends le C#. Si il y a des points ou des notions peu clairs, n'hesite pas, je n'avais pas forcement ecrit mon code dans une optique tres didactique. =p

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    En effet j'ai peur que ce soit un peu dense à assimiler pour un débutant...
    A part ça j'approuve complètement le design !

  10. #10
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Décembre 2007
    Messages
    46
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2007
    Messages : 46
    Par défaut
    Merci pour votre aide, mon professeur m'a finallement donné une solution.
    Il m'a creer un timer qui tourne en boucle mais dont ces actions ne sont faite que si une variable n'est pas vide, et c'est mon traitement qui la rempli, puis elle se vide pour n'avoir l'action qu'une seule fois.

    C'est un peu barbare mais efficace.

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

Discussions similaires

  1. [Socket]Probleme avec CLOSE_WAIT
    Par Raton dans le forum Développement
    Réponses: 4
    Dernier message: 04/01/2017, 09h28
  2. Problème avec " Show plot Tools"
    Par pouette13 dans le forum Interfaces Graphiques
    Réponses: 4
    Dernier message: 30/07/2007, 12h02
  3. Probleme avec les composant socket de builder
    Par lol733 dans le forum C++Builder
    Réponses: 4
    Dernier message: 07/10/2006, 12h22
  4. [socket] Probleme avec connect
    Par sorry60 dans le forum Réseau
    Réponses: 12
    Dernier message: 16/11/2005, 22h01
  5. Probleme avec des socket !
    Par Ptimath44 dans le forum Réseau
    Réponses: 11
    Dernier message: 31/10/2005, 18h11

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