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 :

envoi de plusieurs fichiers en même temps: socket saturée en réception


Sujet :

C#

  1. #1
    Membre du Club
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    décembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

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

    Informations forums :
    Inscription : décembre 2006
    Messages : 113
    Points : 45
    Points
    45
    Par défaut envoi de plusieurs fichiers en même temps: socket saturée en réception
    Bonjour,

    J'ai développé un script de transfert de fichier et ça fonctionne plutôt bien, quand je n'envoie qu'un fichier à la fois!!!
    Cependant si j'envoie 2 fichiers en même temps, ma socket en réception sature et apparemment n'a pas le temps de traiter les paquets de byte[] ( toujours de taille 1400). J'ai fais pas mal de recherches à ce sujet et je ne vois pas de solutions!! Une méthode serait de faire un Thread.sleep(xx) entre l'envoie de chaque paquet mais ce n'est pas très propre.
    Je pensais que les paquets seraient mis dans une file d'attente, jusqu'à temps que la socket de réception les traitent, mais apparemment quand elle en reçoit vraiment trop d'un coup, ça ne fonctionne plus!! et les données reçues dans le buffer sont mal formées.

    Que faire?

  2. #2
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    as tu vérifié que tu lisais bien 1400 octest du coté recepteur ?

    Un grand classique de consommateur/ Emetteur en socket est souvent ce problème

    De plus, ya pas forcément garanti de l'ordre suivant le protocol que tu utilises (UDP ou TCP).

    Et parfois, ton buffer socket peut contenir 3400 octets, et t'en lit que 1400 et le reste est "balancé" dans la nature morte

    Vérifie !
    The Monz, Toulouse
    Expertise dans la logistique et le développement pour
    plateforme .Net (Windows, Windows CE, Android)

  3. #3
    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 : 40
    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
    Points : 39 710
    Points
    39 710
    Par défaut
    fais voir le code, tu t'y es peut-être mal pris...

  4. #4
    Membre du Club
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    décembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

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

    Informations forums :
    Inscription : décembre 2006
    Messages : 113
    Points : 45
    Points
    45
    Par défaut
    C'est du TCP,je reçois les paquets dans l'ordre de taille 1400, ce qui implique que si ce que j'envoie ne fais pas 1400 je comble le manque par un caractère et je reçois 1400 bytes dans le buffer de la socket avec la commande
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    const int PAQUET_SIZE=1400;
    sockConnection.ReceiveBufferSize = PAQUET_SIZE;

    Voici la boucle infinie qui reçoit les paquets de byte de fichier à reconstituer:

    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
    28
     
     
     public void ecoute(Object sock)
            {
                string chaine = null;
                while (true)
                {
                    chaine = null;
                    try
                    {
                        if (sock != null)
                        {
                            byte[] socketReceiveByte = new byte[1400];
                            int k = ((Socket)sock).Receive(socketReceiveByte);
                            chaine = Encoding.UTF8.GetString(socketReceiveByte);
                            //traitement à effectuer sur le paquet
                            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolPreTraitement), chaine);
     
                        }
     
                    }
                    catch (Exception s)
                    {
                        threadListen.Abort();
                        MessageBox.Show(s.ToString());
                    }
                }
            }

  5. #5
    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 : 40
    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
    Points : 39 710
    Points
    39 710
    Par défaut
    A mon avis le problème est que tu ne vérifies pas le nombre d'octets reçus (k). Quelle que soit la quantité de données reçues, tu les traites comme si tu en avais effectivement reçu 1400, même si en fait tu en as peut-être reçu moins...

  6. #6
    Membre du Club
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    décembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

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

    Informations forums :
    Inscription : décembre 2006
    Messages : 113
    Points : 45
    Points
    45
    Par défaut
    comme je l'ai dis dans mon premier poste, j'envoie quoi qu'il arrive toujours 1400 bytes!!!!! car si à l'envoie mon paquet est inférieur je comble le vide avec des caractères pour obtenir cette taille!!!

  7. #7
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 5 993
    Points : 7 901
    Points
    7 901
    Par défaut
    j'envoie quoi qu'il arrive toujours 1400 bytes
    Cela ne veut pas dire que la taille des paquets soit égale à 1400, même si cela arrivera le plus souvent. Certains envois de 1400 byte peuvent être morcelés sur 2 paquets ou groupés avec d'autres envois dans un même paquet.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  8. #8
    Membre du Club
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    décembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

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

    Informations forums :
    Inscription : décembre 2006
    Messages : 113
    Points : 45
    Points
    45
    Par défaut
    Dans mon cas il faut savoir que j'envoie mes paquets de byte dans des entêtes xml, ces entête me servent à identifier l'id du fichier son nom sa taille etc..
    Et donc quand je récupère les bytes dans la socket je les convertis en string pour récupérer la chaine xml.
    Disons qu'en réception, je reçois 2 paquets, voir plus, de taille 1400 et de fichiers différents, en même temps, que se passe t-il concrètement dans ma socket ? normalement il les met à la file non? franchement je n'y vois pas clair, en tout cas, que dois je faire d'après vous? récupérer uniquement ce qu'il y a dans la socket par rapport à la taille (k), je veux bien mais je ne sais pas si ça va résoudre la " malformation" soudaine de ma chaine xml récupérée en réception.

    Si on étudie le comportement de ma méthode si dessus, j'ai une boucle qui itère sur la socket et qui bloque tant qu'il n'y a pas de paquets reçus.
    Dès que j'en reçois un, j'effectue un traitement sur la chaine, mais si je n'ai pas fini d'effectuer le traitement et que j'en reçois 2 paquets de nouveau cette fois-ci en même temps,apparemment il y a problème!

    je précise que j'essaye de reproduire le transfert de fichier à la msn donc 2 personnes peuvent s'envoyer des messages et des fichiers en même temps.
    Ce qui veut dire qu'a un moment dans ma socket je peux me retrouver à traiter un paquet de fichier, des messages(car le mec a flooder) etc...

    pour chaque type(message fichier accusé de reception) j'ai une méthode appropriée qui traite, mais le problème réside vraiment dans le fait que la socket va à un instant T accumuler un maximum de données et je suis vraiment perdu car je ne comprend pas son comportement lorsqu'elle surchargée de paquets en attente?

    Peut-on considérer la socket comme une pile? si oui alors il ne devrait jamais y avoir de problèmes même si y a 5000 paquets en attente dans la socket.

    Bref je suis vraiment perdu? que faire?

  9. #9
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 5 993
    Points : 7 901
    Points
    7 901
    Par défaut
    Tu présupposes une relation obligatoire entre taille des envois et la taille des paquets.

    Supposons que tu fasses 5 envois E1, E2, E3, E4, E5
    Tu pourrais récupérer 4 réceptions :
    • E1 + E2.1
    • E2.2 + E3.1
    • E3.2
    • E4 + E5

    En.1 et En.2 indiquent 2 parties de En envoyées dans des paquets différents.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  10. #10
    Membre du Club
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    décembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

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

    Informations forums :
    Inscription : décembre 2006
    Messages : 113
    Points : 45
    Points
    45
    Par défaut
    Donc pour toi il pourrait y avoir plusieurs types de choses dans la socket (message + paquet de fichier) voir même parfois, pas le paquet entier mais juste un bout...

    Donc faut faire un algo qui parcourt toute la chaine pour voir comment elle est composée? erf!

  11. #11
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 5 993
    Points : 7 901
    Points
    7 901
    Par défaut
    En général, on fait précéder les blocks envoyés par leur longueur.
    Parfois, pour du texte ASCII, on met des caractères spéciaux pour sépare les blocks.

    Dans le cas de blocks de longueur fixe de 1400 octets sans longueur, on utilise un Buffer de longueur 1400.
    Notons LB le nombre d'octets déjà remplis dans ce buffer (LB=0 au départ).
    Notons R le nombres d'octets lus via ta fonction de lecture (cette fonction devant juste lire un maximum de LB-1400 octets à partir de Buffer[LB]) .
    L'algo à mettre en place ressemblera à ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void ProcessReceptionEvent
    {
      bool Continue=true ;
      While (Continue) 
      { 
        R=MySocketRead(Buffer,LB,1400-LB) ;
        if (LB+R==1400) { MyProcessBlock(Buffer) ; LB=0 ; }
        else { LB=LB+R ; Continue=false ;}
      }
    }
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  12. #12
    Membre du Club
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    décembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

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

    Informations forums :
    Inscription : décembre 2006
    Messages : 113
    Points : 45
    Points
    45
    Par défaut
    Je précise que j'envoie mes paquets dans des entêtes xml avec la taille
    R est la taille de ce que contient le tableau de bytes [1400] sans tenir compte des caractères "\0"?

    Si je me réfère à ton algo:
    si LB+R!=1400
    alors c'est que un paquet arrive en 2 fois et donc je dois le garder en mémoire pour le compléter avec la premiere partie du paquet?

  13. #13
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 5 993
    Points : 7 901
    Points
    7 901
    Par défaut
    dans mon algo, R= nombre d'octet renvoyé par le read en ayant mis la valeur maxi à 1400 si le buffer est vide ou moins si il est partiellement rempli par le(s) read(s) précédent(s).
    si LB+R!=1400
    alors c'est que un paquet arrive en 2 fois et donc je dois le garder en mémoire pour le compléter avec la premiere partie du paquet?
    Oui et surtout ne pas dépasser 1400 avant de processer le buffer.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  14. #14
    Membre du Club
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    décembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

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

    Informations forums :
    Inscription : décembre 2006
    Messages : 113
    Points : 45
    Points
    45
    Par défaut
    qu'appelles tu processer le buffer? y at-il une commande C# pour l'effectuer?

  15. #15
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 5 993
    Points : 7 901
    Points
    7 901
    Par défaut
    qu'appelles tu processer le buffer?
    traiter ton bloc logique de 1400 octets.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  16. #16
    Membre du Club
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    décembre 2006
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : Canada

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

    Informations forums :
    Inscription : décembre 2006
    Messages : 113
    Points : 45
    Points
    45
    Par défaut
    Resalut Mec j'ai fait ce que tu m'as dis et en regardant en debug, j'ai effectivement vu que, comme je reçois trop de paquets en même temps, il rentre dans le :

    else { LB=LB+R ; Continue=false ;}
    {
    chaine = Encoding.UTF8.GetString(socketReceiveByte);
    }

    et dans ma string chaine qui récupère le contenu du buffer j'ai effectivement récupéré un morceau du paquet et dans l'envoie suivant la seconde partie du morceau, donc tu avais raison:

    Quand la socket est "surchargée" elle tronque et c'est à nous de reconstituer!!!
    Par contre c'est chiant car dans le second morceau du paquet reçu juste après, comme y avait de la place dans le buffer, il a rajouté le début d'un nouveau paquet, donc au final dans le buffer je me retrouve à la fin d'un paquet et le début d'un autre, tu vois ce que je veux dire?
    Imagine s'ils s'envoient du texte au même moment, ca pourrait faire 3 choses dans le buffer, plutôt tendu de tout reconstituer!!!!

    Maintenant je me pose une question pour reconstituer de la meilleure façon possible?

    Etant donné que nous somme en TCP, nous recevons les paquets dans l'ordre ce qui veut dire que je recevrais toujours les tierces morceaux d'un paquet tronqués dans l'ordre, donc je me dis que j'ai qu'a les mettre dans une liste en attendant? et quand j'ai reconstitué mon truc bim je l'envoei dans le process, qu'en penses-tu???

Discussions similaires

  1. lancer(parcer) plusieurs fichiers en même temps
    Par sculpteur dans le forum Shell et commandes GNU
    Réponses: 8
    Dernier message: 15/10/2010, 18h49
  2. [XL-2003] Difficultés à ouvrir plusieurs fichiers en mêmes temps
    Par anfernus dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 21/07/2010, 14h53
  3. Réponses: 38
    Dernier message: 26/09/2008, 18h46
  4. Ouverture de plusieurs fichiers en même temps ?
    Par nicolas.sitbon dans le forum POSIX
    Réponses: 42
    Dernier message: 08/08/2008, 00h35
  5. ouvrir plusieurs fichiers en même temps
    Par diiity dans le forum Windows
    Réponses: 0
    Dernier message: 03/08/2007, 19h26

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