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 :

SOCKET Traiter en parallèle des trames tcp avec le threadPool


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Novembre 2006
    Messages : 113
    Par défaut SOCKET Traiter en parallèle des trames tcp avec le threadPool
    Bonjour,
    J'avais des problèmes de lenteurs lors de la réception de paquet pour les fichiers un peu plus gros, car je traitais les trames une par une à la file. Voilà en gros le code de réception

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
       byte [] paquetRecu=new byte[1024];
       while(true)
       {
         int k= socket.receive(paquetRecu)
         //ensuite je dois traiter le paquet pour en extraire la position dans le fichier total et bien sûr, ajouter le contenu des octets pour la reconstitution
         traitementPaquetRecu(paquetRecu)
       }
    Donc voilà à la base, j'écoute et je traite le paquet,ça fonctionne mais c'est assez lent. Donc je me suis dit " et si je traitais les paquets en parallèle!!"

    donc j'ai modifié la boucle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    byte [] paquetRecu=new byte[1024];
       while(true)
       {
         int k= socket.receive(paquetRecu)
     
         // je dois créer un nouvel objet à chaque fois avant d'envoyer dans le    thread, sinon la valeur sera modifié pour tous les threads lors de la  réception d'un nouveau paquet
         byte [] paquetTraite=new byte [1024];
         paquetRecu.CopyTo(paquetTraite,0);
     
        //ThreadPaquetRecu est la méthode contenant traitementPaquetRecu()
          ThreadPool.QueueUserWorkItem(new  WaitCallback(ThreadPaquetRecu), paquetTraite);
    }
    En rajoutant cette simple ligne, c'est effectivement méchamment rapide!!!!!!!!! mais y a un hic que je ne comprend pas!!!

    En faisant un "console.writeLine(numero de bloc en cours+ numBloc)" dans la méthode threadé(traitementPaquetRecu()), j'obtiens:

    1
    2
    4
    5
    6
    6
    6
    7
    7
    7
    8
    8
    8
    8
    10
    ....
    Je précise que le numero de bloc est une information que j'envoie dans chaque paquet pour calculer à quel position je dois placer la série d'octets.

    Bref vous constatez qu'en utilisant threadPool c'est rapide, mais je traite apparemment des paquets en double et il y en certains qui sont totalement "zappés" au vue du listing des numéros de bloc traité ci-dessus...

    Au final je reconstitue mon fichier rapidement mais quelques trous dedans, pourquoi le threadPool se comporte de cette facon?

    NEED HELP!!!!!

  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
    Si tu veux faire du parallélisme, il faut gérer la synchronisation entre les threads, sinon tu te retrouves avec un résultat complètement imprévisible... une socket est une ressource critique, elle ne doit pas être utilisée par 2 threads à la fois.

    Essaie de profiler ton code pour voir ce qui prend du temps (réception ou traitement). Eventuellement, sépare la réception du traitement, et parallélise le traitement, pas la réception.

  3. #3
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    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 197
    Par défaut
    plutot qu'un thread pool, j'aurais utilisé un seul thread

    une variable type queue
    dans ta gestion du tcp quand tu recois un paquet, tu l'ajoutes à la queue et c'est tout

    dans l'autre thread qui est démarré avant tu fais une boucle infinie (type while true)
    et tu regardes si la queue contient quelque chose tu le traites sinon tu attends un peu via system.threading.thread.sleep(100)

    la réception peut idéalement etre faite sur un thread différent du thread principal aussi
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

Discussions similaires

  1. Envoyer des trames ethernet avec python
    Par olivierguzzi dans le forum Général Python
    Réponses: 1
    Dernier message: 19/05/2013, 19h01
  2. Créer un petit serveur TCP avec des Sockets ?
    Par UiYuki dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 25/09/2009, 09h31
  3. [TCP/IP] Capter des trames TCP/IP
    Par au_record dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 16/01/2006, 10h53
  4. Problème avec l'envoi d'une trame TCP
    Par fredoBreton dans le forum API, COM et SDKs
    Réponses: 14
    Dernier message: 17/11/2005, 20h19
  5. [GZIP] Compression des trames TCP ?
    Par SteelBox dans le forum Développement
    Réponses: 6
    Dernier message: 11/01/2005, 05h34

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