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 :

Reception/Envoi incomplet de Byte[] avec TCP.


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Cybercope
    Homme Profil pro
    Programmeur amateur
    Inscrit en
    Mai 2014
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Programmeur amateur

    Informations forums :
    Inscription : Mai 2014
    Messages : 78
    Par défaut Reception/Envoi incomplet de Byte[] avec TCP.
    Bonjour !

    J'ai une connexion TCP Client/Serveur qui fonctionne très bien.

    A l'aide de ce protocole, j'envoie des tableaux de byte[].

    Cependant, lors de la réception, je ne reçois pas tous les bytes.

    Je m'explique :

    J'ai une image. Je récupère les bytes de cette images dans un tableau avec cette fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public static byte[] ImageToByte(Image img)
            {
                try
                {
                    ImageConverter converter = new ImageConverter();
                    return (byte[])converter.ConvertTo(img, typeof(byte[]));
                }
                catch
                {
                    return null;
                }
            }
    j'envoie ensuite ce tableau de cette manière :

    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
     
    public void SendImg()
            {
                try
                {
                    Image img = null;
                    img = pictureBox1.Image;
     
                    byte[] bytesend = ImageToByte(img);
     
                    SEND("IM/" + bytesend.Length.ToString());
                    stream.Write(bytesend, 0, bytesend.Length);
                }
                catch
                {
                }
            }
    Comme vous pouvez le voir, avant d'envoyer le tableau avec Stream.Write, j'envoie "IM/ + taille du tableau"
    Cet envoi sert à "dire" au destinataire qu'il faut qu'il s’apprête à recevoir une image d'une taille bien précise.

    En effet, je récupère l'image de cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    byte[] bytes = new byte[buffersize];
    stream.Read(bytes, 0, buffersize);
    ShowImage(bytes);
    NB: buffersize = taille du tableau

    la fonction qui permet d'avoir l'image avec le tableau de bytes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public Image byteArrayToImage(byte[] byteArrayIn)
            {
                try
                {
                    MemoryStream ms = new MemoryStream(byteArrayIn);
                    Image returnImage = Image.FromStream(ms);
                    return returnImage;
                }
                catch
                {
                    return null;
                }
            }

    Le problème : je reçois à chaque fois l'image, mais celle-ci est souvent incomplète. je n'arrive pas a savoir pourquoi, et je ne sais pas si c'est le tableau qui n'est pas envoyé en entier ou si le tableau n'est pas lu en entier. J'ai aussi pensé a une éventuelle "perte", mais j'avoue ne pas avoir plus d'informations sur ce problème.

    Merci de votre aide !


    J'ai juste une petite question, j'ai cette ligne dans mon projet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    [DllImport("user32.dll")]
    public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
    j'ai beau chercher ne trouve pas vraiment d'information sur ce que signifie "extern", même si je pense que c'est parce que l'on fait référence à une class externe au projet. Si une âme charitable pouvait m'expliquer en deux mots cette ligne, je lui serai reconnaissant !



    Ind6x

  2. #2
    Expert confirmé

    Homme Profil pro
    Responsable déploiement (SCCM, InTune, GPO)
    Inscrit en
    Juillet 2014
    Messages
    3 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Responsable déploiement (SCCM, InTune, GPO)
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2014
    Messages : 3 218

  3. #3
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 200
    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 200
    Par défaut
    extern c'est pour déclarer une méthode/fonction qui n'est ni dans ton exe ni dans les dll en référence mais dans une autre dll, en l'occurrence ici c'est une dll de windows nommée user32.dll

    concernant le tcp il ne fait pas de perte (par rapport à l'udp qui ne garanti ni l'ordre d'arrivée, ni l'arrivée)
    mais par contre un envoi ne correspond pas toujours à une réception, déjà parce qu'il y a buffer (qui doit être de 8ko par défaut), il n'est pas possible d'envoyer 500ko d'un coup par exemple, c'est découpé en plusieurs paquets
    (y a d'autres qui jouent, comme si le buffer n'est pas rempli windows peut décider d'attendre un peu si des fois tu envoies autre chose par la suite ca sera mis au bout)
    c'est pour ca qu'en général on a un protocole d'envoi (comme la taille du message en début de trame, des identifiants et séparateurs dans le message, des caractères de fin de trame ...)
    quand tu recois des octets il faut donc les ajouter à un buffer plus gros (genre un list<byte>) et redemander la réception
    lors d'une réception c'est à toi de vérifier dans ton cache tu as un message entier auquel cas tu le traites

    dans ton cas si tu as un int en début de trame qui contient le nombre d'octets tu attends d'avoir assez d'octets

    sachant qu'en fin de "message" tu peux recevoir la fin de ton image plus les octets de la trame suivante, donc c'est réellement à toi de découper comme il faut

    c'est pour ca que WCF est bien pratique, il encapsule tout ceci et d'autres choses pour faire en sorte que côté client tu appelles une méthode en lui donnant les éventuels paramètres, et l'exécution se fait côté serveur sans que tu n'ai à réfléchir au transport des messages
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    Membre confirmé Avatar de Cybercope
    Homme Profil pro
    Programmeur amateur
    Inscrit en
    Mai 2014
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Programmeur amateur

    Informations forums :
    Inscription : Mai 2014
    Messages : 78
    Par défaut
    Merci de m'aider !

    J'ai enfin pu m'ôter un doute sur extern !

    Pour ce qui est de mon problème de tableau, j'ai beau essayer, je n'y parvient pas.

    Je n'ai pas encore un très bon niveau en C#, et j'arrive tout juste de VB.Net !

    J'ai un peu de mal a voir comment je pourrais résoudre mon problème.

    Merci !

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 200
    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 200
    Par défaut
    si tu arrives de vb.net il n'y a qu'une différence de syntaxe avec c#, en quelques jours on peut passer de l'un à l'autre


    ca manque de code pour voir si tu es déjà sur la bonne piste, car dans le principe après un read de toute facon il t'en faudra un autre, sinon tu ne pourras recevoir qu'une seule fois

    sinon comme tu as écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    stream.Read(bytes, 0, buffersize);
    tu as du chercher à quoi servait le 0, donc tu peux mettre autre chose que 0 pour continuer de remplir le tableau au dernier offset
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre confirmé Avatar de Cybercope
    Homme Profil pro
    Programmeur amateur
    Inscrit en
    Mai 2014
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Programmeur amateur

    Informations forums :
    Inscription : Mai 2014
    Messages : 78
    Par défaut
    Problème résolu !

    Je poste ici la solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    byte[] data = new byte[buffersize];
                int offset = 0;
                int remaining = data.Length;
                while (remaining > 0)
                {
                    int read = stream.Read(data, offset, remaining);
                    if (read <= 0)
                        throw new EndOfStreamException
                            (String.Format("End of stream reached with {0} bytes left to read", remaining));
                    remaining -= read;
                    offset += read;
                }
                return data;
    Merci !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 04/11/2010, 08h44
  2. Envoi/reception tableau byte socket TCP
    Par jhon_milou dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 01/06/2007, 11h40
  3. Envoi incomplet avec methode post
    Par Tr@nkill dans le forum ASP
    Réponses: 8
    Dernier message: 16/05/2005, 12h14
  4. Envois d'un mail Avec CDont
    Par PrinceMaster77 dans le forum ASP
    Réponses: 3
    Dernier message: 25/10/2004, 17h34
  5. [TIdSMTP] Envoi d'un mail avec authentification ?
    Par BACUS dans le forum C++Builder
    Réponses: 4
    Dernier message: 16/06/2004, 16h18

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