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 :

Réseau - utilisation/compréhension des mécanismes liés à TcpClient.Read() -


Sujet :

C#

  1. #1
    Membre averti
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    59
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 59
    Par défaut Réseau - utilisation/compréhension des mécanismes liés à TcpClient.Read() -
    Bonjour,

    Je dois réaliser une application très simple.

    Elle se connecte sur une machine sur un port précis. Ce port émet des messages texte en Tcp.

    L'application qui écoute sur le port j'ai réussis à la faire grâce à ce tutoriel: http://skoffler.developpez.com/dotnet/tcpclient/ .

    Je met le code que j'ai actuellement, à voir s'il y a des améliorations à produire ou non.
    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
        static void Main(string[] args)
        {
          byte[] monReadBuffer = new byte[214];
          TcpClient monClientTcp = new TcpClient("192.168.1.2", 3217);
          monClientTcp.NoDelay = true;
          NetworkStream monFlux = monClientTcp.GetStream();
          int nbLus;
          while ((nbLus = monFlux.Read(monReadBuffer, 0/*offset*/, monReadBuffer.Length)) != 0)
          {
     
            //read peut déclencher exception
            String messageRecu =
                System.Text.Encoding.ASCII.GetString(monReadBuffer, 0, nbLus/*tout le buffer n'est pas utilisé*/);
            Console.WriteLine("Nb d'octet recus: {0}", nbLus);
            Console.WriteLine("message:#{0}#", messageRecu.ToString());
          }
          monFlux.Close();
          monClientTcp.Close();
          Console.WriteLine("test");
          Console.ReadLine();
        }
    Les messages reçu font tous une taille de 214 bytes. Ils sont composés de chiffre et lettre.
    Le but de cette application est de récupérer le message et l'insérer en base de donnée.

    1/ J'ai fait quelques tests, j'ai augmenté la taille de mon buffer à 2000 bytes, et lorsque je reçois un message il me l'affiche directement et n'attend pas de lire les 2000 bytes, je ne comprends pas pourquoi? Je n'ai pas de contrôle sur la machine distante et ne sais pas trop comment les messages sont construit et envoyé. Est-ce qu'il y a dans le paquet tcp un champ qui indique le nombre de byte envoyé et donc ainsi la fonction Read s'arrête de lire dès qu'elle à lu tout le message? (Je n'ai pas trouvé cette information sur les pages que j'ai lu dans la Msdn)

    2/ Comment être sûr de ne rater aucun message lorsque j'écoute les messages arrivant?
    J'ai lu quelques documents notamment la msdn sur les classes TcpClient NetworkStream etc... Mais je ne vois pas comment m'assurer de bien récupérer tous les messages, j'ai vu que l'on peut utiliser TcpClient en mode Asynchrone (ou Socket dans le même mode) est-ce que cela peut m'apporter quelque chose?

    3/ Dois-je utiliser les Threads un pour la réception des messages et un pour l'insertion dans la Bdd. Dans le sens où un message est reçu, j'appelle une fonction dans un Thread séparé en lui passer en paramètre le message.
    Je vais avoir un peu de traitement à faire sur ce message il est composé de plusieurs champs donc un peu de découpage de String, je ne pense pas que ce soit très très long, et la fréquence des messages n'est pas très très élevé, si j'arrive à un message par seconde c'est déjà bien. (Les messages proviennent d'appel téléphonique entrant/sortant)
    Donc est-ce utile de séparer l'insertion en base de données dans un Thread séparé.

    4/ Comment m'assurer que lorsque je me connecte je ne sois pas au milieu de la réception d'un message, ou alors c'est impossible car quand je me connecte, l'ordinateur distant va commencer en m'envoyer les messages mais si il y avait un message en cour, il ne me sera pas envoyé à moitié mais je vais simplement le rater.

    5/ Quand je me connecte avec mon application je vois tous les messages, il y a 3 retour à la ligne dans le message j'ai tenté de les supprimer avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    messageRecu.Replace("\n", "$$$$");
    messageRecu.Replace("\r", "####");
    Pour bien voir si j'arrivais à les supprimer mais ca n'a pas fonctionné, est-ce que j'ai mal écris le Replace? Je ne comprends pas pourquoi ca ne passe pas.

    6/ Dernière question:
    Mon application devra tourner en permanence, est-ce mieux de créer un service windows par exemple pour être sûr que mon application continue de fonctionner en permanence ou bien un simple programme console que l'on lance au démarrage sur une machine?


  2. #2
    Membre chevronné Avatar de npuzin
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    265
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2007
    Messages : 265
    Par défaut
    Le serveur peut etre une appli console, mais si tu veux faire ca bien, un service windows sera plus adapte et plus fiable.

    Ton serveur doit etre multithread.

    Un thread qui "ecoute" en permanence et des qu'il recoit qqchose il lance un nouveau thread pour treater le message.

  3. #3
    Membre averti
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    59
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 59
    Par défaut
    Citation Envoyé par npuzin Voir le message
    Le serveur peut etre une appli console, mais si tu veux faire ca bien, un service windows sera plus adapte et plus fiable.

    Ton serveur doit etre multithread.

    Un thread qui "ecoute" en permanence et des qu'il recoit qqchose il lance un nouveau thread pour treater le message.
    => D'accord pour le service windows, dans un premier temps je vais rester sur une application console pour tester et ensuite je le passerais sur un service windows car je n'ai jamais fait de service windows. Je regarderais quand tout mon programme fonctionnera.
    Merci npuzin

    Voilà après un peu de recherche et de lecture j'ai produit le code suivant. Seul soucis je ne sais pas si c'est bien multithread comme ca doit l'être.
    Pour l'instant je me limite à mettre l'affichage dans le nouveau Thread, ensuite j'aurais ma fonction d'insertion en base de données.
    J'ai bien mon affichage avec mes messages comme en telnet donc je suppose que tout est ok?
    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
    class Program
    {
      static void Main(string[] args)
      {
        byte[] monReadBuffer = new byte[214];
        TcpClient monClientTcp = new TcpClient("192.168.1.2", 3217);
        monClientTcp.NoDelay = true;
        NetworkStream monFlux = monClientTcp.GetStream();
        int nbLus;
        while ((nbLus = monFlux.Read(monReadBuffer, 0/*offset*/, monReadBuffer.Length)) != 0)
        {
          //read peut déclencher exception
          String messageRecu = System.Text.Encoding.ASCII.GetString(monReadBuffer, 0, nbLus/*tout le buffer n'est pas utilisé*/);
          ThreadPool.QueueUserWorkItem(ShowMessage, messageRecu);
        }
        monFlux.Close();
        monClientTcp.Close();
        Console.WriteLine("test");
        Console.ReadLine();
      }
     
      private static void ShowMessage(object objectTmp)
      {
        Console.WriteLine("Nb d'octet recus: {0}", ((String)objectTmp).Length);
        Console.WriteLine("message:#{0}#", ((String)objectTmp).ToString());
      }
    }
    Si oui alors les questions 3 et 6 sont répondues.

    Concernant la question 1/ :
    J'ai continué mes recherches concernant les segments TCP. J'ai regardé les en-tête et ils ne contiennent pas la taille du segment TCPcontrairement à UDP dont l'en-tête contient la taille de l'en-tête plus la partie Data.

  4. #4
    Membre averti
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    59
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 59
    Par défaut
    En lisant d'autre posts sur le forum j'ai vu deux manières de démarrer une fonction dans un nouveau Thread:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ThreadPool.QueueUserWorkItem(CallMessageManager, (object)rawMessage);
    Et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Thread thread = new Thread(new ParameterizedThreadStart(CallMessageManager));
    thread.Start(rawMessage);
    Y a-t-il une version préférable à l'autre?

    Ci-joint mon projet complet si quelqu'un pouvait vérifier que ce n'est pas mal fait, surtout au niveau des Threads.
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/11/2012, 10h13
  2. [Réseau] Utilisation de TcpClient
    Par neptune dans le forum Framework .NET
    Réponses: 7
    Dernier message: 29/05/2009, 23h00
  3. Réponses: 2
    Dernier message: 14/12/2007, 01h47
  4. [FLASH MX] Prob de compréhension des bouttons
    Par WriteLN dans le forum Flash
    Réponses: 13
    Dernier message: 16/10/2003, 17h01
  5. Problème de compréhension des ensembles
    Par Cornell dans le forum Langage
    Réponses: 6
    Dernier message: 07/02/2003, 22h07

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