Identification d'un client sur une appli client serveur en C#

Résolu
dadew37 Messages postés 7 Date d'inscription mercredi 18 mars 2009 Statut Membre Dernière intervention 24 mars 2009 - 23 mars 2009 à 14:35
meme06 Messages postés 11 Date d'inscription vendredi 8 septembre 2006 Statut Membre Dernière intervention 11 mai 2009 - 11 mai 2009 à 20:08
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

dadew37 Messages postés 7 Date d'inscription mercredi 18 mars 2009 Statut Membre Dernière intervention 24 mars 2009
23 mars 2009 à 18:45
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 !!!
3
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 29
23 mars 2009 à 14:55
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
---------------------
0
dadew37 Messages postés 7 Date d'inscription mercredi 18 mars 2009 Statut Membre Dernière intervention 24 mars 2009
23 mars 2009 à 15:02
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.
0
dadew37 Messages postés 7 Date d'inscription mercredi 18 mars 2009 Statut Membre Dernière intervention 24 mars 2009
23 mars 2009 à 15:06
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.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
billou_13 Messages postés 860 Date d'inscription jeudi 4 mars 2004 Statut Membre Dernière intervention 19 août 2014 29
23 mars 2009 à 15:18
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
---------------------
0
dadew37 Messages postés 7 Date d'inscription mercredi 18 mars 2009 Statut Membre Dernière intervention 24 mars 2009
23 mars 2009 à 15:22
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 !!!
0
dadew37 Messages postés 7 Date d'inscription mercredi 18 mars 2009 Statut Membre Dernière intervention 24 mars 2009
24 mars 2009 à 10:08
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
0
dadew37 Messages postés 7 Date d'inscription mercredi 18 mars 2009 Statut Membre Dernière intervention 24 mars 2009
24 mars 2009 à 10:13
La partir de code qui me semble être à l'origine de mon problème :

bytesRead = clientStream.Read(message, 0, 4096);
0
meme06 Messages postés 11 Date d'inscription vendredi 8 septembre 2006 Statut Membre Dernière intervention 11 mai 2009
11 mai 2009 à 20:08
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.
0
Rejoignez-nous