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

Collection et Stream Java Discussion :

[java] probleme de transfert de tableau de byte


Sujet :

Collection et Stream Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 21
    Par défaut [java] probleme de transfert de tableau de byte
    Bonjour !
    Je suis en train d'essayer d'envoyer des fichiers d'une machine a une autre par transfert de datagram paquet UDP.
    Pour etre sur que ce que j'envoi et ce que je recoi est bien la meme chose au byte pret, j'affiche ce que j'envoi juste apres l'avoir envoyé, et j'affiche ce que j'écris juste aprés l'avoir écris (a chaque fois j'affiche les bytes) : voici le code :

    // Pour l'envoi, ce que j'envoi correspondant a tab[part - 1] :
    System.out.println("Envoi du data de la partie " + part + " du fichier " + nameFile + ": \n" + Arrays.toString(tab[part - 1]));

    // Pour la reception, ce que je recoi correspond a data :
    System.out.println("Reception de la partie " + p + " du fichier " + nameFile + " : \n" + Arrays.toString(data));

    Voici les resulats :

    Envoi de la partie 1 de taille 2055 du fichier ecran.png a la machine localhost/127.0.0.1:20020 :
    [-119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 48, 0, 0, 0, 48, 8, 6, 0, 0, 0, 87, 2, -7, -121, 0, 0, 0, 6, 98, 75, 71, 68, 0, -1, 0 ... ]

    Reception de la partie 1 du fichier ecran.png :
    [-17, -65, -67, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 48, 0, 0, 0, 48, 8, 6, 0, 0, 0, 87, 2, -17, -65, -67, 0, 0, 0, 6, 98, 75, 71, 68, 0, -17, -65, -67, 0 ...]

    Apres etude des ces 2 lignes manifestement semblables mais avec quelques differences, il semble que ce soit avec un nom negatif que cela pose un pb, a savoir que pour un nombre negatif envoyé, je recoi -17, -65, -67 .
    Quelqu'un saurait me dire d'ou cela peut venir, et comment resoudre ce probleme ?
    Bien cordialement,

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par thotoss Voir le message
    Quelqu'un saurait me dire d'ou cela peut venir, et comment resoudre ce probleme ?
    Pour cela il nous faudrait le code utilisé pour l'envoi et la réception des données...

    a++

  3. #3
    Membre très actif Avatar de unknow0
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 452
    Par défaut
    Bonjour,

    ca pareil bizare d'avoir des diffenrence entre l'envoie et la reception.
    il faudrai voir se que tu fait entre parceque la :s

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 21
    Par défaut
    Bonjour et merci de me repondre !
    le pb c'est que mon code est assez long, vous voulez quelle partie du code precisement ?
    merci!

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 21
    Par défaut
    Bon je vous poste la partie du code dans laquelle jenvoi le tableau, laffiche, puis je le recupere plus loin et je laffiche aussi :

    Code d'envoi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
                        tampon = ("req_data " + nameFile + " " + (cpt + 1) + " " + tab[cpt].length + " " + new String(tab[cpt])).getBytes();
                        paquet = new DatagramPacket(tampon, tampon.length, adresseDistante, portDistant);
                        socketUploader.send(paquet);
                        message = new String(tampon, 0, paquet.getLength());
                        System.out.println("Envoi de la partie " + (cpt + 1) + " de taille " + tab[cpt].length + " du fichier " + nameFile + " a la machine " + adresseDistante + ":" + portDistant + "   : " + Arrays.toString(tab[cpt]));


    Code de reception :
    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
                    tampon = new byte[5096];
                    paquet = new DatagramPacket(tampon, tampon.length,  
                                                              adresseDistante, portDistant);
                    try {
                        socketDownloader.receive(paquet);
                    } catch (Exception ex) {
                        System.out.println("Erreur Downloader : " + ex);
                    }
                    // On recupere le message recu.
                    message = new String(tampon, 0, paquet.getLength());
                    // On traite le message.
                    if (message.startsWith("req_data " + nameFile)) {
                        String[] tab = message.split(" ", 5);
                        int p = Integer.decode(tab[2]);
                        int length = Integer.decode(tab[3]);
                        byte[] data = new byte[Math.min(length, lengthMax)];
                        data = tab[4].getBytes();
                        String nomFicSortie = repertoireLocal + "/" + nameFile;
                        String extFicSortie = ".[FS]." + tab[2];
                        File ficSortie = new File(nomFicSortie + extFicSortie);
                        FileOutputStream fluxSortie = new FileOutputStream(ficSortie);
                        fluxSortie.write(data, 0, Math.min(length, lengthMax));
                        fluxSortie.flush();
                        fluxSortie.close();
                        System.out.println("Reception de la partie " + p + " du fichier " + nameFile + "   : " + Arrays.toString(data));

    Bon je sais que c'est peut etre pas tres claire, hesitez pas a poser des questions!
    merci davance!

  6. #6
    Membre très actif Avatar de unknow0
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 452
    Par défaut
    alors apres quelque test il semblerai que sa soit les conversion de byte[] en string qui fouterai le bordel.
    deja je ne voie pourquoi tu covertie ton tableau tab en string pour l'envoie.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 21
    Par défaut
    Comment faire alors ? je dois concatener ma chaine avec le tableau de byte a envoyer alors ?

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 21
    Par défaut
    Bon j'ai testé sans faire la conversion du data que je veu envoyer en string, mais j'ai exactement le meme probleme (pour les bytes negatif qui donne -17, -65, -67). Voici le code d'envoi que j'ai testé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
                        String header = "req_data " + nameFile + " " + (cpt + 1) + " " + tab[cpt].length + " ";
                        byte[] head = new byte[header.length()];
                        byte[] data = new byte[tab[cpt].length];
                        head = header.getBytes();
                        data = tab[cpt];
                        tampon = new byte[head.length + data.length];
                        System.arraycopy(head, 0, tampon, 0, head.length);
                        System.arraycopy(data, 0, tampon, head.length, data.length);
     
                        paquet = new DatagramPacket(tampon, tampon.length, adresseDistante, portDistant);
                        socketUploader.send(paquet);
                        message = new String(tampon, 0, paquet.getLength());
                        System.out.println("Envoi de la partie " + (cpt + 1) + " de taille " + tab[cpt].length + " du fichier " + nameFile + " a la machine " + adresseDistante + ":" + portDistant + "   : " + Arrays.toString(tab[cpt]));

    Je comprend vraiment pas cette conversion quand il y a un bit negatif ...

  9. #9
    Membre très actif Avatar de unknow0
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 452
    Par défaut
    oui mais la aussi a la reception il faut utiliser directement le tableau de byte[] pour recupere les donner sinon il y aura le meme probleme avec la conversion en String
    (humm d'ailleur c'est peu etre du au caractaire non imprimable ou non valide.)

  10. #10
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Déjà ceci ne sert strictement à rien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
                        byte[] head = new byte[header.length()];
                        head = header.getBytes();
    Lors de la seconde affectation le tableau défini sur la première ligne est perdu.

    L'opérateur = est un opérateur d'affectation et non pas un opérateur de copie !!!



    Sinon avec cette modif tu as toujours le même problème ? Tu as bien changé le code de réception de la même manière ?

    a++

  11. #11
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Par défaut
    hello,

    comme dit précédemment, la fonction getBytes() (et ses copines) n'est pas à utiliser seule, sans spécifier un charset, sinon on arrive aux pires horreurs.

    Là, les bytes qui posent problème semblent clairement être ceux qui affichent une valeur négative. Or en java, le type 'byte' est signé ; donc est codé de -127 à 127. Et pour coder un byte négatif, on utilise une technique de 'complément à un' ou un truc du genre. Donc quand on voit sur ta sortie 'texte' une valeur négative, il faut en fait lire 'un byte avec le bit de poids fort qui est à 1 (ou en termes de 'byte non signé', une valeur > 127)'.

    Or, quand tu fait un getBytes, j'imagine que par défaut le charset qui sera utilisé sera UTF-8 ... qui a pour particularité:

    - de coder chaque caractère dont la valeur ASCII vaut moins de 127 sur un seul octet, le même qu'en ASCII.

    - par contre, quand on dépasse 127, on code sur plusieurs caractères (pour 255 <= valeur <= 128, un premier caractère d'échappement qui vaut 0x110xxxxx et un second qui vaut 0x10xxxxxx, les 'x étant les bits de la valeur à coder).


    D'où le problème je pense: le charset choisi (ou plutôt ici 'pas choisi') utilise une technique d'encodage qui fait qu'un caractère en entrée peut être codé sur un ou plusieurs bytes en sortie (et inversement).

    En utilisant un autre charset qui fait du 1 octet <=> 1 caractère (genre "US-ASCII" ou "ISO-8859-1", cf. Charset), ça devrait déjà mieux se passer amha.




    PS: au cas où, pour rappel: (un byte = un octet en Anglais ; un byte est composé de 8 bits).

Discussions similaires

  1. [Socket][File] Envoyer un tableau de byte
    Par itsmii dans le forum Entrée/Sortie
    Réponses: 14
    Dernier message: 30/01/2014, 09h10
  2. Java Card - Convertir une tableau de byte en clé publique
    Par garudah dans le forum Développement Mobile en Java
    Réponses: 0
    Dernier message: 03/07/2009, 11h19
  3. Probleme récupération d'un pdf sous forme d'un tableau de byte
    Par wallyfr dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 31/08/2006, 16h10
  4. probleme d allocation avec un tableau de BYTE
    Par e1lauren dans le forum C++
    Réponses: 5
    Dernier message: 06/05/2005, 13h42
  5. Réponses: 12
    Dernier message: 04/10/2004, 19h18

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