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

Entrée/Sortie Java Discussion :

[ObjectInputStream]Pb avec GZIP et ByteArrayInputStream


Sujet :

Entrée/Sortie Java

  1. #1
    Membre du Club
    Inscrit en
    Avril 2004
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 8
    Par défaut [ObjectInputStream]Pb avec GZIP et ByteArrayInputStream
    Salut à tous,

    Tout d'abord c'est mon premier post, alors je félicite les responsables de ce site pour sa qualité en général, en plus c'est en français
    Sinon, je suis au bord de la dépression nerveuse. Je cherche à utiliser des sockets en SSL, et y envoyer directement des objets zippés. En fait mon prog utilise une classe de message.
    (Désolé si je suis long)
    Le principe :
    (Envoi des données)
    - Je crée une socket avec SSL et je récupère son flux (inCon en entrée, outCon en sortie côté client/serveur)
    - Je transforme un objet en tableau d'octets, car apparemment les sockets SSL n'acceptent pas les flux ObjectOutputStream. J'utilise donc un ObjectOutputStream sur un ByteArrayOutputStream. (Au passage j'aimerais bien y insérer un GZIPOutputStream). J'enregistre le résultat dans un tableau.
    - J'envoie le tableau de bytes directement sur l'OutputStream de la socket.
    (Réception des données)
    - Je lis les données sur le flux d'entrée de la socket, que je stocke dans un tableau de bytes.
    - Je crée un ByteArrayInputStream sur le tableau de bytes
    - Je crée un ObjectInputStream sur le ByteArrayInputStream, et je lis directement l'objet.

    Problèmes :
    1- Lorsque j'insère un GZIPInputStream/GZIPOutputStream entre les ByteArray et Object Streams, la compression fonctionne mais pas la décompression
    2- sans GZIP : Le premier échange fonctionne. Lorsque je récupère le second mesage, bien que tous mes objets soient créés dans la boucle, je lis le même message....
    Explication : à la réception, je lis un tableau de bytes depuis le flux d'entrée. Le tableau est différent d'un message à l'autre. A ce moment, je crée de nouveaux ByteArray et Object InputStream. Malgré cela, le message obtenu à la fin est le même qu'au premier message recu.....

    Je vous mets pour mieux comprendre la fonction de réception :
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
        public Message getMessage() {
            ArrayList byteArrays = new ArrayList();
            boolean finish=false;
            isFree=false;
            Message result = null;
            int nb=0;
     
            try {
                // Read the data from the socket InputStream
                while (!finish) {
                    byte[] buf = new byte[4096];
                    System.out.println("Filling a buffer");
                    //int nb = input.read(buf);
                    nb = inCon.read(buf);
                    System.out.println(nb+" bytes read from the stream to the buffer");
                    if (nb == -1) finish = true;
                    else if(nb<4096) {byteArrays.add(buf);finish = true;}
                    else byteArrays.add(buf);
                }
                System.out.println(byteArrays.size()+" arrays of bytes read");
     
                // Create an array of bytes containing all the bytes received
                int size = 4096*(byteArrays.size()-1)+nb;
                byte[] resultArray = new byte[size];
                int i=0;
                for (Iterator ite = byteArrays.listIterator(); ite.hasNext(); ) {
                    byte[] buf = (byte[]) ite.next();
                    for (int j=0;j<4096;j++) {
                        if (i*4096+j < size)
                            resultArray[i*4096+j]=buf[j];
                        else break;
                    }
                    i++;
                }
     
                // Read the data with an ObjectInputStream, using a ByteArrayInputStream
                System.out.println("size of the array : "+resultArray.length);
     
                ByteArrayInputStream baInput = new ByteArrayInputStream(resultArray);
                //ObjectInputStream in = new ObjectInputStream(new GZIPInputStream(baInput));
                ObjectInputStream in = new ObjectInputStream(baInput);
                result = (Message)in.readObject();
                System.out.println("received message : "+result.toString());
                in.close();
     
                /*result = (Message)in.readObject();*/
            }
            catch (IOException e) {
                log.add(log.RMI, log.MAJOR,"(getMessage) IO Exception : "+e.getLocalizedMessage());
            }
            catch (ClassNotFoundException cne) {
                log.add(log.RMI, log.MAJOR,"(getMessage) ClassNotFound Exception : "+cne.getLocalizedMessage());
            }
            isFree=true;
            return result;
        }
    Voilà, si quelqu'un m'a compris et aurait ne serait-ce qu'une piste de solution, je lui en serai reconnaissant mais alors à un point....
    Merci d'avance
    [ Modéré par vedaer ]
    -> Ajout des balises code
    [ Merci de respecter les Règles du Forum ]

  2. #2
    Membre du Club
    Inscrit en
    Avril 2004
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 8
    Par défaut
    désolé vedaer , j'essaierai de faire mieux la prochaine fois....
    Bon, en fait j'ai réglé mon pb. Il me reste juste un détail de certificat pour l'établissement de la communication en SSL et tout fonctionnera.
    Voila, si ca intéresse quelqu'un je pourrai indiquer une solution pour faire de l'objectStream compressé en GZIP sur SSL...

  3. #3
    Membre Expert
    Avatar de Ioan
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    737
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 737
    Par défaut
    Bonjour,
    Ce n'est pas grave.
    Penses juste à mettre le sujet en résolu et à donner ta solution. Ca pourrais aider les personnes ayant le même problème.
    @+
    Les FAQs Java, J2EE, JDBC, Struts > Les cours > Le Forum Java.
    Merci de respecter les règles du club.
    Mon blog : quelques news sur Java, Linux et le monde de l'Open Source.

  4. #4
    Membre du Club
    Inscrit en
    Avril 2004
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 8
    Par défaut
    Bon, ben vouala comment j'ai fait :
    * Le problème est que les différents flux évolués comme ObjectInputStream ne fonctionnent pas forcément lorsqu'on a du ssl. Donc, je n'envoie de données que via un OutputStream, et les récupère via un InputStream. J'y envoie des flux de bytes, donc je dois transformer mes objets en tableaux de bytes en premier lieu.
    - Voici la fonction que j'utilise pour transformer mes objets en flux d'octets compressés :
    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 static byte[] ObjectToBytes(Serializable object)throws Exception {
            try {
                ByteArrayOutputStream bo = new ByteArrayOutputStream();
                GZIPOutputStream go = new GZIPOutputStream(bo);
                ObjectOutputStream oo = new ObjectOutputStream(go);
                oo.writeObject(object);
                go.finish();
                oo.flush();
                return bo.toByteArray();
            } catch (Exception e) {
                throw e;
            }
        }
    J'ai mis cette fonction dans une classe d'utilitaires, car si la routine était placée directement dans ma fonction d'envoi réseau, ça ne fonctionnait qu'au premier envoi.... va savoir pourquoi?
    Petite remarque, ne pas oublier le finish() sur le GZIPOutputStream, sinon à la réception le deflater ne trouve pas la fin du flux compressé
    Pour récupérer l'objet la fonction est la même à l'envers :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
        public static Serializable BytesToObject(byte[] bytes)throws Exception {
            try {
                ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
                GZIPInputStream gi = new GZIPInputStream(bi);
                ObjectInputStream oi = new ObjectInputStream(gi);
                Serializable output = (Serializable) oi.readObject();
                return output;
            } catch (Exception e) {
                throw e;
            }
        }
    Maintenant, juste les 2 fonctions d'envoi et de réception du message, mais alors là ne m'en veuillez pas si elles ne sont pas optimisées....
    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 void sendMessage(Message message) {
            isFree=false;
            try {
                // outCon est mon OutputStream sur ma socket en SSL
                // NetUtils est ma classe d'utilitaires, la fonction ObjectToBytes est statique
                outCon.write(NetUtils.ObjectToBytes(message));
                outCon.flush();
            }
            catch (Exception e) {
                System.exit(1);
            }
            isFree=true;
        }
    La réception, un peu plus tordue pour obtenir un tableau de bytes sans en connaitre la taille à l'avance....
    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
    29
    30
    31
    32
    33
    34
    35
    36
     
        public Message getMessage() {
            ArrayList byteArrays = new ArrayList();
            boolean finish=false;
            Message result = null;
            int nb=0;
     
            try {
                // Read the data from the socket InputStream
                while (!finish) {
                    byte[] buf = new byte[4096];
                    nb = inCon.read(buf);
                    if (nb == -1) finish = true;
                    else if(nb<4096) {byteArrays.add(buf);finish = true;}
                    else byteArrays.add(buf);
                }
     
                // Create an array of byte[] containing all the byte[] received
                int size = 4096*(byteArrays.size()-1)+nb;
                byte[] resultArray = new byte[size];
                int i=0;
                for (Iterator ite = byteArrays.listIterator(); ite.hasNext(); ) {
                    byte[] buf = (byte[]) ite.next();
                    for (int j=0;j<4096;j++) {
                        if (i*4096+j < size)
                            resultArray[i*4096+j]=buf[j];
                        else break;
                    }
                    i++;
                }
                result = (Message)NetUtils.BytesToObject(resultArray);
            }
            catch (Exception e) {
            }
            return result;
        }
    voilà. Moi mes objets sont de la classe Message qui est Serializable. Maintenant, vous pouvez établir une socket sécurisée ou non, sans influence sur vos types de flux. Si vous avez de petits objets à envoyer, vous pouvez bypasser le passage dans des GZIPStreams.

    J'espère que ces explications serviront à quelqu'un.

    @+,
    riloo

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 18
    Par défaut
    hello,
    Je suis entrain de me charger de la partit server d'une application qui communique en ssl login pass puis si tout est ok envoie une serie de fichier zip.C'est en cour de test la.
    J'utilise ceci comme flux i/o :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    try {
          socketTrans = (SSLSocket) _serveursocketSSL.accept();
          sortieD = new DataOutputStream(socketTrans.getOutputStream());
          entreeD = new DataInputStream(socketTrans.getInputStream());
        }
        catch (IOException ex) {
        }
    et je l'ai recois comme ça :
    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
     
    int chunksize = 1024;
          Hashtable files = new Hashtable();
          byte bytes[] = new byte[chunksize];
          ByteArrayOutputStream bytesStream = new ByteArrayOutputStream();
          DataOutputStream bytestream = new DataOutputStream(bytesStream);
          int writecount;
          int togo = taille;
          while (togo > 0) {
            writecount = (togo >= chunksize ? chunksize : togo);
            entreeD.read(bytes, 0, writecount);
            bytestream.write(bytes, 0, writecount);
            togo = togo - writecount;
          }
     
          bytestream.flush();
          entreeD.close();
    On est un peu magniaque,les zip sont aussi crypte.Apres les avoir recu,je l ai decrypte puis je dezip et fait mes test dessus.
    Si tu as besoin d'aide pm moi.

    Cordialement

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

Discussions similaires

  1. Probleme pour décompresser avec gzip
    Par Mathieu Salles dans le forum Général Java
    Réponses: 5
    Dernier message: 23/04/2013, 10h55
  2. Problème avec Gzip
    Par Xenon03 dans le forum Langage
    Réponses: 12
    Dernier message: 22/11/2011, 16h31
  3. Compression de chaine de caractères avec GZip
    Par sebdec dans le forum VB.NET
    Réponses: 2
    Dernier message: 29/09/2011, 22h51
  4. [VB.NET]Décompression avec Gzip
    Par Yaoox dans le forum Windows Forms
    Réponses: 26
    Dernier message: 14/01/2011, 18h30
  5. Compresser plusieurs fichiers avec GZip
    Par Fly3R dans le forum Windows Forms
    Réponses: 2
    Dernier message: 02/09/2007, 13h54

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