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 socket serveur (attente du client) [Débutant]


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2011
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2011
    Messages : 610
    Par défaut
    Bonsoir à tous!!

    Voici un problème que je ne comprend pas!
    Tout d'abord je suis débutant en c#, le but de mon appli est de créer un serveur /client via internet. Hors j'ai un petit soucis avec le code :
    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
     
    richTextBox1.Text = "Démmarage du serveur...\n";
     
                srv = new TcpListener(IPAddress.Any, 3000); //initialise TcpListener détecte automatiquement les connexion, 
                // IPaddress.Any accecpte toute les connexion IP sur le port 3000
                richTextBox1.Text += "Initialisation du serveur...\n";
                srv.Start();                                            //On lance la boucle d'écoute
                richTextBox1.Text += "Le serveur est prêt à écouter\n";
     
     
               while (true)                                            //Boucle à l'infini
                {
                     Socket client = srv.AcceptSocket();                 // Bloquer quand il n'y a pas de client, AcceptSocket renvoi un socket tout prêt
                     if (client.Connected)
                     {
                        richTextBox1.Text += "client connecté\n";
                        Thread thr = new Thread(new ThreadStart(ListenThread)); //création d'un thread client
                        richTextBox1.Text += "thread actif\n";
                        thr.Start();                                            //Démarre thread
                     }
                }
    Mon erreur se trouve à la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Socket client = srv.AcceptSocket();
    Enfin ce n'est pas une erreur, c'est ce qui me fait planter mon appli.
    J'aurai voulu votre avis sur mon code, je crèe le serveur avent le client.
    Car il sera toujours actif je voudrait juste qu'il attende le client sans planter

    Je ne comprend pas du tout pourquoi..

    Et pour ListenThread voici la suite:

    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
     
    void ListenThread()
            {
                Socket sock = client;                               //récupère le socket prêt
                while (sock.Connected != false)                      //Parler au client tant que ce n'est pas fini
                {
                    Byte[] rep = new Byte[32767];                   //Création d'un tableau de byte
                    int count = sock.Receive(rep, rep.Length, 0);   //stock donnée dans rep, longeur du champs dans count
                    string srep = Encoding.ASCII.GetString(rep);    //Convertir les donnée en string
                    string reponse = srep.Substring(0, count);      //On garde les données exacte grâce à la taille
                    richTextBox1.Text += reponse + "\n";
                    switch (reponse)
                    {
                        case "deconnexion":
                            richTextBox1.Text += "déconnexion\n";
                            sock.Shutdown(SocketShutdown.Both);         //si deconnexion on ferme le socket en ecriture/lecture
                            sock.Close();                               // libere le socket
                            break;
                    }
                }
                Thread.CurrentThread.Abort();                          //On tue le thread 
                richTextBox1.Text += "thread tué \n";
            }
    Merci de m'aider

  2. #2
    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
    Quelle est l'exception que tu obtiens ? (type, message, stacktrace)

  3. #3
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 200
    Par défaut
    si tu as un plantage, synonyme d'erreur, il convient de donner les détails de l'erreur
    si tu as un freeze, il contient d'utiliser le vocabulaire adapté lorsqu'on s'exprime en public

    si c'est un freeze, c'est tout à fait normal, msdn (l'aide) le précise
    Accept est une méthode bloquante, tant que personne se connecte, l'exécution s'arrête là, et ca continue à la connexion d'un client

    solutions possibles :
    - mettre ca dans un thread (comme ca le thread qui rafraichit l'interface n'est pas bloqué)
    - utiliser les méthodes begin* comme beginaccept (un callback est appelé à la connexion d'un client)

    et si tu codes les 2 côtés de la connexion, tu peux jeter un oeil sur WCF, c'est 100x plus pratique au final
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    Membre chevronné
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2011
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2011
    Messages : 610
    Par défaut
    Pour tomlev, je n'est pas d"exception, juste mon application gèle.

    Pour Pol63, Dsl de mettre mal exprimé, mai oui comme je viens de le dire mon appli gèle.
    Je veux bien mettre un thread mais pour quel partie?
    Juste pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Socket client = srv.AcceptSocket();
    Parce que j'ai essayé sans succès

    Dsl pour mes erreurs de débutant.

    Et les méthode begin* (je ne connais pas), quel est l'intérêt?

    Merci! de votre aide..

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 200
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 200
    Par défaut
    accept est bloquant
    beginaccept ne l'est pas
    beginaccept (et autres beginreceive, beginsend ...) démarrent un thread qui fait accept (et autres) puis quand ca se débloquent ils appellent un callback que tu leur a fournit (= méthode de retour, presque comme un évènement)

    au lieu d'avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void {
    code
    accept
    code }
    tu as
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void {
    code
    beginaccept (callback)}
     
    void callback {
    endaccept
    code }
    car si la suite du code doit être effectuée après l'acceptation, celle ci se retrouve dans le callback

    les threads sont peut etre plus simple que les callbacks à comprendre ...
    dans les 3 cas (j'inclus wcf) il y a des tutos via le lien en haut de page
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre chevronné
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2011
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2011
    Messages : 610
    Par défaut
    Voilà j'ai suivi tes conseils!
    Mais il me reste un soucis lol, je ne peut pas afficher se que le client m'envoi!
    Sinon une erreur apparait à la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    this.Invoke(new testecriture(testecrituretext1), "Message recu : "+content+" \n");
    Erreur : Keyword 'this' is not valid in a static property, static method, or static field initializer
    Erreur : An object reference is required for the non-static field, method, or property 'ServeurAppli.Serveur.testecrituretext(string)'
    Je ne vois pas comment elle se crée vu que j'écrit déjà à partir du thread qui contient la ligne..

    Voici le code :
    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
     
             public void Run_Click(object sender, EventArgs e)
            {
                IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());   // retourne les information réseaux
                IPAddress ipAddress = ipHostInfo.AddressList[0];            //Adresse ip retournée par le DNS
                IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); //combine IP et port
                richTextBox1.Text += "Démarage du serveur...\n";
     
                listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //Ipv4 / Envoi - reception / TCP
                richTextBox1.Text += "Socket créer\n";
     
                listener.Bind(localEndPoint);
                listener.Listen(100);
                richTextBox1.Text += "Serveur prêt à écouter...\n";
                test = new Thread(testmeth);
                test.Start();
     
            }
    Je lance un thread à la fin pour éviter que mon programme gèle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
            public void testmeth()
            {
                while (true)
                {
                    allDone.Reset();  // définit l'éenevement à l'état non signalé
                    this.Invoke(new testecriture(testecrituretext), "Dans boucle..\n"); //Permet décrire dans richbox sans conflit de thread
                    listener.BeginAccept(new AsyncCallback(AcceptReceiveDataCallback), listener);
                    allDone.WaitOne();
                }
               this.Invoke(new testecriture(testecrituretext),"Sortie boucle..\n");
            }
    Voilà le contenu du thread avec BeginAccept, j'utilise this.Invoke pour écrire dans ma richbox.
    Jusqu'ici tout va bien! Si vous remarqué des erreurs n'hesiter pas à me les dire

    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 AcceptReceiveDataCallback(IAsyncResult ar)
            {
                this.Invoke(new testecriture(testecrituretext), "dans accetp donné..\n");
                listener = (Socket)ar.AsyncState;
                Socket handler = listener.EndAccept(ar); // renvoi le nombre d'octet recu
     
                StateObject state = new StateObject();
                state.workSocket = handler;
                this.Invoke(new testecriture(testecrituretext), "Avant reception");
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
     
            }
     
     
            public static void ReadCallback(IAsyncResult ar)
            {
                String content = String.Empty;
                //this.Invoke(new testecriture(testecrituretext), "Entrer dans beginreceive");
     
                StateObject state = (StateObject)ar.AsyncState;
                Socket handler = state.workSocket;
     
     
                int bytesRead = handler.EndReceive(ar); // lit donné du socket client
     
                if (bytesRead > 0)
                {
                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead)); // on stock les donné de suite
     
                    content = state.sb.ToString();
                    this.Invoke(new testecriture(testecrituretext), "Message recu : "+content+" \n");
                }
            }
    L'erreur se trouve donc à la dernière ligne, ce qui m'empeche donc de récupérer se que je viens de récupérer

    Merci de votre aide

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

Discussions similaires

  1. Problème communication serveur/client avec Socket
    Par Nicolas74 dans le forum Entrée/Sortie
    Réponses: 0
    Dernier message: 03/12/2009, 16h54
  2. Réponses: 3
    Dernier message: 27/10/2008, 22h31
  3. Problème communication sockets serveur mutli-client
    Par muad'dib dans le forum Réseau
    Réponses: 5
    Dernier message: 17/05/2007, 02h21
  4. problème socket serveur.
    Par deck_bsd dans le forum Réseau
    Réponses: 2
    Dernier message: 13/12/2006, 19h33
  5. Réponses: 20
    Dernier message: 10/07/2006, 16h53

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