Identification d'un client sur une appli client serveur en C# [Résolu]

Signaler
Messages postés
7
Date d'inscription
mercredi 18 mars 2009
Statut
Membre
Dernière intervention
24 mars 2009
-
Messages postés
11
Date d'inscription
vendredi 8 septembre 2006
Statut
Membre
Dernière intervention
11 mai 2009
-
Bonjour tout le monde !

Je suis débutant en C#, et pourtant l'entreprise ou je suis me demande de développer une appli en C# qui gère du client serveur via des sockets TCP. Et ceci dans le but de me former pour entreprendre un projet.

J'ai donc développé un code client et un code serveur multithreadé. Tout fonctionne correctement mais on me demande maintenant d'être capable d'itenfier le client par un numéro et donc de savoir quand il ouvre une socket et la ferme (connexion/deconnexion du serveur).

Je cherches depuis un sacré moment et rien ne me vient à l'esprit, j'ai réussi à faire afficher le numéro du client via un compteur lors de la connexion mais je sais que c'est très limité et ça ne répond pas réellement à la demande.

Pouvez vous m'aider, je vous remercies d'avance.

Rémi

Voici mon code serveur :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.Collections;
using System.IO;

namespace ConsoleApplication1
{
    class ServerTCP
    {
        private System.Net.Sockets.TcpListener tcpListener;
        private Thread listenThread;
        private int numberClientConnect;
        private int j;

        //private static ArrayList Clients = new ArrayList();

        public ServerTCP()
        {
            this.tcpListener = new System.Net.Sockets.TcpListener(IPAddress.Any, 3000);
            this.listenThread = new Thread(new ThreadStart(ListenForClients));
            this.listenThread.Start();
        }

        private void ListenForClients()
        {
            this.tcpListener.Start();
            Console.WriteLine("Server started");
            while (true)
            {

                for (this.numberClientConnect = 1; this.numberClientConnect <= 101; this.numberClientConnect++)
                {
                    //bloqué tant qu'un client est connecté au serveur
                    TcpClient client = this.tcpListener.AcceptTcpClient();

                    //créé un thread pour garder la communication
                    // avec un client connecté
                    Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));

                    clientThread.Start(client);

                    Clients.Add(this.numberClientConnect);

                    Console.WriteLine("Client connected {0}", this.numberClientConnect);

                    this.j = 1;
                    j++;
                }
            }
        }

        private void HandleClientComm(object client)
        {
            TcpClient tcpClient = (TcpClient)client;
            NetworkStream clientStream = tcpClient.GetStream();

            byte[] message = new byte[4096];
            int bytesRead;

            while (true)
            {
                string mess = string.Empty;

                try
                {
                    //blocage tant qu'un client envoie un message
                    bytesRead = clientStream.Read(message, 0, 4096);
                    System.Console.WriteLine("Try Message reception");
                }
                catch
                {
                    //une erreur de socket s'est produite
                    break;
                }

                if (bytesRead == 0)
                {
                    //IEnumerator ClientsEnumerator = Clients.GetEnumerator();

                    //while (ClientsEnumerator.MoveNext())
                    //{
                    //    //le client s'est deconnecté du serveur
                    //    //System.Console.WriteLine("Client {0} disconnected",((ClientsEnumerator.Current).(this.numberClientConnect)));
                    //    System.Console.WriteLine("Client disconnected");
                    //    this.numberClientConnect--;
                    //    break;
                    //}

                    //le client s'est deconnecté du serveur
                    //System.Console.WriteLine("Client {0} disconnected",((ClientsEnumerator.Current).(this.numberClientConnect)));
                    System.Console.WriteLine("Client disconnected");
                    this.numberClientConnect--;
                    break;

                }
                   
                //le message a été reçu avec succès
                Console.WriteLine("Message reception successfull\n");
                ASCIIEncoding encoder = new ASCIIEncoding();
                System.Console.WriteLine("Client message : ");
                mess += encoder.GetString(message, 0, bytesRead);
                System.Console.WriteLine(encoder.GetString(message, 0, bytesRead));
            }
            tcpClient.Close();
        }
    }
}

9 réponses

Messages postés
7
Date d'inscription
mercredi 18 mars 2009
Statut
Membre
Dernière intervention
24 mars 2009

J'ai fini par trouver ma solution tout seul !

J'utilises une hashtable dans laquelle j'utilises le client comme clé et l'identifiant comme objet. Ainsi je conserves un identifiant à chaque création de socket dans la hashtable et je peux le récupérer dans la console quand je le veux !

Merci de ton aide billou_13 !!!
Messages postés
860
Date d'inscription
jeudi 4 mars 2004
Statut
Membre
Dernière intervention
19 août 2014
23
Bonjour,

Et pourquoi ne pas utiliser ton simplement un système de login/password qui te permettra d'identifier le client qui se connecte ?
Ou sinon, tu peux tout aussi bien récupérer le nom de la machine qui se connecte et donc identifier l'utilisateur.

Mais la solution dépend de ton problème. Pour t'aider, nous aurions besoin de plus d'information.
Quel est concrètement ton problème ? pourquoi te demande-t-on d'identifier les clients ?

Sinon, pour ton projet, ne désespère pas (je suis débutant en C#, et pourtant...). Tu m'as l'air très malheureux
Je peux te dire que c'est plutôt cool que tu sois sur un projet C#. Et c'est "on ne peut plus intéressant" que de faire des projets de ce type.
Tu verras qd tu voudras trouver du boulot le point positif de cette expérience auprès du marché

Bon courage,

Billou_13
Bask En Force

--------------------------------------------------------------------
Connaître la réponse est une chose, savoir pourquoi en est une autre
---------------------
Messages postés
7
Date d'inscription
mercredi 18 mars 2009
Statut
Membre
Dernière intervention
24 mars 2009

Merci de ta réponse pour commencer.

En fait le but est d'identifier le client uniquement par le biais du code serveur. Chaque socket ouverte est différente :

- Client 1 -> 1ere socket ouverte
- Client 2 -> 2eme socket ouverte

Mon code serveur est sous la forme d'une application console (le client est un Form). Cette console doit renvoyer des informations à l'écran telle que :

au lieu de :
- System.Console.WriteLine("Client message : "); ----> je puisses obtenir à l'écran "Client 1 message : ..."

Je ne sais pas si c'est très clair. Une socket ouverte prend un identifiant (1, 2, 3, 4...) en fonction du nombre de client. Et le but est d'identifier quelle socket se ferme et donc quel client se deconnecte.

Merci d'avance de votre aide.
Messages postés
7
Date d'inscription
mercredi 18 mars 2009
Statut
Membre
Dernière intervention
24 mars 2009

Ah et oui un détail.

Mon client ne doit pas envoyer son login par exemple. Le client est quelconque et c'est au serveur de savoir départager les différents clients.

Ma console doit être capable de dire quel client écrit un message, quel client se deconnecte et quel client se connecte.

J'avoues que je n'y arrive pas. Et je suis d'accord avec toi le C# c'est vraiment intéressant. Auparavant je codais en C++ et je dois avouer que le C# est un soulagement pour faire du Framework.
Messages postés
860
Date d'inscription
jeudi 4 mars 2004
Statut
Membre
Dernière intervention
19 août 2014
23
Donc, ta solution qui consiste à attribuer un numéro au client qui se connecte est tout à fait justifiée et correcte (tu peux aussi identifier un client par son adresse IP).
Par contre, pour savoir qu'un client s'est déconnecté, ceci n'est pas facile. Car, tant qu'il n'y a pas de communication entre le client et le serveur, le serveur ne peux pas le savoir :)

Il te faut donc implémenter un système de ping afin de déterminer qui est toujours présent.
Si tu le souhaites, j'ai un début de source sur le sujet qui devrait fortement t'intéresser. Je peux te l'envoyer.
PS pour les autres: je n'ai pas mis sur code sources car je souhaiterais avoir une version livrable avant et je n'ai pas le temps de la finir en ce moment.

Bon courage,

Billou_13
Bask En Force

--------------------------------------------------------------------
Connaître la réponse est une chose, savoir pourquoi en est une autre
---------------------
Messages postés
7
Date d'inscription
mercredi 18 mars 2009
Statut
Membre
Dernière intervention
24 mars 2009

En fait pour savoir si je suis connecté ou non au serveur j'utilises une variables bytesRead dans laquelle je mets les bytes que je lis de la stream du client :

bytesRead = clientStream.Read(message, 0, 4096);

C'est ce qui me permets de savoir si je suis connecté de par le test :

                if (bytesRead == 0)
                {
                    //le client s'est deconnecté du serveur
                    System.Console.WriteLine("Client disconnected");
                    this.numberClientConnect--;
                    break;

                }
Mais en effet si ton code peut m'aider ça m'interesse !!!
Messages postés
7
Date d'inscription
mercredi 18 mars 2009
Statut
Membre
Dernière intervention
24 mars 2009

Re bonjour !

J'ai une nouvelle question...
Lorsque je lis le stream du client, j'utilises un buffer de 4096 bytes donc largement suffisant dans mon cas.

On me demande de réduire ce buffer à 2 bytes mais de malgré tout afficher le message en une seule ligne dans la console.

Je ne trouves pas où ajouter la boucle qui pourrait m'aider à ça !

Quelqu'un peut il m'aider ?

Merci d'avance
Messages postés
7
Date d'inscription
mercredi 18 mars 2009
Statut
Membre
Dernière intervention
24 mars 2009

La partir de code qui me semble être à l'origine de mon problème :

bytesRead = clientStream.Read(message, 0, 4096);
Messages postés
11
Date d'inscription
vendredi 8 septembre 2006
Statut
Membre
Dernière intervention
11 mai 2009

Je sais que tu as trouvé une methode je poste juste une autre pour ceux que ca interesse.

puisque tu as plusieur client tu as plusieur thread d'ecoute .

une methode consiste a donner un int number unique a chacun de c thread.

regarde du coté de cette methode .

Interlocked.Increment(ref m_clientCount);

chaque fois que le client parle tu peu identifier son ID facilement.