Partage
  • Partager sur Facebook
  • Partager sur Twitter

C# et communication ethernet

(Protocoles TCP/IP)

    12 avril 2011 à 10:06:56

    Bonjour,

    Je développe actuellement une application C# sur système embarqué (en SmartDeviceProject dans VS) et j'ai besoin de mettre en place une communication via un câble Ethernet. Pour info je vous explique mon projet : je veux créer un tableau de bord pour un kart. Donc à l'aide un pc embarqué (windows embedded compact 7) faire l'acquisition de données via des capteurs (vitesse, température etc ...), les traiter, et les afficher. La partie délicate, (sachant que j'utilise et je connais le langage C# que depuis une semaine, merci le cours du site du zéro ^_^) réside dans l'acquisition des données, le reste devrait se dérouler sans encombre.

    J'ai trouvé des infos sur le site MSDN, à propos des Socket Class et TcpClient Class. Mais les codes sont un peu complexes, même si j’ai compris la globalité.

    Ma question est donc :
    Avez-vous une ébauche de code qui :
    - Ouvre une connexion avec un câble Ethernet (protocole TCP/IP)
    - Configure la connexion
    - Lis les données disponibles (existe-t-il une fonction simple « read » qui lit les données qu’on pourrait stocker dans une variable en vue de les afficher ?)
    - Éventuellement stock les données dans une variable et/ou les affiche dans l'interface
    - Ferme la connexion

    Avec cet exemple, je pourrais lire le code et comprendre davantage la procédure de connexion, pour au final créer ma propre communication Ethernet.

    Si vous avez aussi l’adresse d’un cours bien expliqué et complet, je suis preneur, en gros, toute information à ce propos ^_^.

    Merci pour vos réponses. :D
    Je souhaite une excellente journée à tous les lecteurs du site !

    Brygoth
    • Partager sur Facebook
    • Partager sur Twitter
      14 avril 2011 à 9:42:09

      Up (Edit du sujet, plus d'info et question modifiée :D )
      • Partager sur Facebook
      • Partager sur Twitter
        14 avril 2011 à 13:06:16

        Voici un exemple très simple d'utilisation de TcpListener et TcpClient (côté serveur).
        Je suis sûr que tu peux en trouver plein d'autres sur le net ;)

        Le "dialogue" client/serveur présenté ici est le suivant:
        - connexion du client
        - envoi d'un message du client sous forme de string
        - réponse du serveur sous forme de string "OK, bien reçu!"
        - fin de la connexion.

        using System;
        using System.Text;
        using System.Diagnostics;
        using System.IO;
        using System.Net.Sockets;
        using System.Net;
        
        public class DemoServer
        {
            private TcpListener m_listener;
            bool _started = false;
        
            public DemoServer()
            {
            }
        
            public void Start(IPEndPoint endpoint)
            {
                m_listener = new TcpListener(endpoint);
                m_listener.Start();
                _started = true;
        
                // On attend qu'un client se connecte
                m_listener.BeginAcceptTcpClient(HandleClient, null);
            }
        
            private void HandleClient(IAsyncResult res)
            {
                if(_started)
                {
                    try
                    {
                        // Un client s'est connecté. On le récupère:
                        TcpClient client = m_listener.EndAcceptTcpClient(res);
        
                        // On se remet immédiatement à l'écoute d'un autre client qui pourrait arriver:
                        m_listener.BeginAcceptTcpClient(HandleClient, null);
        
                        // Et on engage en même temps la conversation avec le client connecté:
                        this.ProcessClient(client);
                    }
                    catch(Exception ex)
                    {
                        Trace.TraceError("Server Error : {0}", ex.Message);
                    }
                }
            }
        
            public void Stop()
            {
                _started = false;
                m_listener.Stop();
            }
        
            public void ProcessClient(TcpClient client)
            {
                // A ce stade la connexion est établie, 
                // le dialogue entre le client et le serveur peut commencer.
                try
                {
                    // On suppose ici que c'est le client qui parle en premier.
                    // On attend donc un message de sa part (qui est ici une string).
                    // Le message reçu ne peut pas dépasser 5000 octets.
        
                    StreamReader reader = new StreamReader(client.GetStream(), Encoding.UTF8);
                    char[] buffer = new char[5000];
                    int nbrBytesRead = reader.Read(buffer, 0, buffer.Length);
                    string messageReceived = new string(buffer);
        
                    // On traite le message d'une façon ou d'une autre.
                    // Ici on lance un événement pour qu'il soit traité ailleurs:
                    if(this.MessageReceived != null)
                        this.MessageReceived(this, new MessageReceivedEventArgs() { Message = messageReceived });
        
                    // On envoie une réponse au client avant de fermer la connexion.
                    StreamWriter writer = new StreamWriter(client.GetStream());
                    writer.Write("OK, bien reçu !");
                    writer.Flush();	// ne pas oublier de flusher pour que le message parte !
        
                }
                catch(Exception ex)
                {
                    Trace.TraceError("Server Error : {0}", ex.Message);
                }
                finally
                {
                    client.GetStream().Close();
                    client.Close();
                }
            }
        
            public event EventHandler<MessageReceivedEventArgs> MessageReceived;
        }
        
        public class MessageReceivedEventArgs : EventArgs
        {
            public string Message { get; set; }
        }
        

        Exemple d'utilisation du serveur:

        public class Program
        {
            static void Main(string[] args)
            {
                DemoServer server = new DemoServer();
                server.MessageReceived += server_MessageReceived;
        
                // on écoute le port 666
                server.Start(new IPEndPoint(IPAddress.Loopback, 666));
        
                Console.WriteLine("En attente de messages. Presser Entrée pour quitter.");
                Console.ReadLine();
        
                server.Stop();
            }
        
            static void server_MessageReceived(object sender, MessageReceivedEventArgs e)
            {
                Console.WriteLine("Message reçu: " + e.Message);
            }
        }
        

        Je n'ai pas fait de code pour la partie client; est-ce que tu en auras besoin ? :euh:
        • Partager sur Facebook
        • Partager sur Twitter
          14 avril 2011 à 14:04:50

          Merci beaucoup, les commentaires sont magiques, j'ai enfin compris tout ça. Il faudra le relire plusieurs fois avant de se lancer, mais je suis content. Merci pour la pédagogie :D. J'ai une petite question tout de même :

          Pour répéter la lecture des données (par exemple l'acquisition de la vitesse du véhicule toutes les demi-secondes), je peux utiliser un timer, et créer une boucle qui se stoppe à l'arrêt du timer (par l'utilisateur par exemple) ?

          - Si oui, la boucle doit inclure uniquement le {try}, {le try et le catch}, {le try, le catch et le finally}, ou autre ? (ligne 55 du code, méthode : ProcessClient)

          - Si non, le try fait office de boucle, et effectue l'acquisition jusqu'à fermeture du serveur par l'utilisateur ou le client, et le timer est inutile ?


          Pour ce qui est du code côté client, sur le site MSDN on trouve un exemple pas mal commenté, donc pas de soucis si tu ne l'écris pas ;-).

          static void Connect(String server, String message) 
          {
            try 
            {
              // Create a TcpClient.
              // Note, for this client to work you need to have a TcpServer 
              // connected to the same address as specified by the server, port
              // combination.
              Int32 port = 13000;
              TcpClient client = new TcpClient(server, port);
          
              // Translate the passed message into ASCII and store it as a Byte array.
              Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);         
          
              // Get a client stream for reading and writing.
             //  Stream stream = client.GetStream();
          
              NetworkStream stream = client.GetStream();
          
              // Send the message to the connected TcpServer. 
              stream.Write(data, 0, data.Length);
          
              Console.WriteLine("Sent: {0}", message);         
          
              // Receive the TcpServer.response.
          
              // Buffer to store the response bytes.
              data = new Byte[256];
          
              // String to store the response ASCII representation.
              String responseData = String.Empty;
          
              // Read the first batch of the TcpServer response bytes.
              Int32 bytes = stream.Read(data, 0, data.Length);
              responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
              Console.WriteLine("Received: {0}", responseData);         
          
              // Close everything.
              stream.Close();         
              client.Close();         
            } 
            catch (ArgumentNullException e) 
            {
              Console.WriteLine("ArgumentNullException: {0}", e);
            } 
            catch (SocketException e) 
            {
              Console.WriteLine("SocketException: {0}", e);
            }
          
            Console.WriteLine("\n Press Enter to continue...");
            Console.Read();
          }
          


          Merci

          Brygoth
          • Partager sur Facebook
          • Partager sur Twitter
            15 avril 2011 à 11:26:00

            A priori c'est le client qui envoie les données toutes les 500ms, donc ton timer doit être situé côté client.
            Quant au serveur, il doit effectivement boucler (sans délais) pour lire les informations qui arrivent au compte-gouttes.

            Un bloc try-catch ne fait jamais office de boucle. Ici je pense que tu peux placer une boucle while dans le try, qui boucle jusqu'à ce que le client signale qu'il n'a plus rien à émettre (ou jusqu'à ce qu'une erreur se produise, cette erreur étant alors récupérée par le catch). Ca suppose que la connexion reste ouverte du début à la fin: il faut donc que le client évite d'établir une nouvelle connexion à chaque fois.

            Le code du serveur sera donc "bloqué" dans la méthode ProcessClient() jusqu'à ce que le client cesse de transmettre des données. Ce n'est pas un problème, car la méthode HandleClient() (et donc ProcessClient() aussi) a été appelée dans un thread dédié à la communication entre le serveur et le client entrant. Tu peux donc donc boucler aussi longtemps que nécessaire :)
            • Partager sur Facebook
            • Partager sur Twitter

            C# et communication ethernet

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown