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 :

Problème lecture InputStream


Sujet :

Entrée/Sortie Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 57
    Par défaut Problème lecture InputStream
    Bonjour à tous,

    J'ai une application Android avec laquelle j'effectue une connexion bluetooth avec un autre appareil et une communication est établie entre les deux.
    Je poste cela ici car mon soucis est au niveau I/O.

    J'essaie d'expliquer cela clairement :

    J'utilise un Thread pour lire mon InputStream. Je me suis rendu compte en affichant le résultat que j'avais des anomalies dans le contenu récupéré.

    Résultat attendu :
    1101=xx
    1001=xx
    2045=xx
    ...
    Résultat constaté :
    0101=xx
    1011=xx
    2045=xx
    ...
    Ces anomalies sont assez aléatoires mais sont jamais identiques. Je suis partie sur la piste de solution suivante : lors de la lecture de mon InputStream j'ai un décalage...

    J'ai ainsi rajouté un reset() sur mon inpustream après le read() afin qu'il se repositionne correctement.

    Résultat : Je dois appeler deux fois mon thread qui lit le inputstream car la première fois il me renvoit "1" et c'est tout. En l'appelant une deuxième fois il me renvoit alors la suite sans décallage :
    001=xx
    1001=xx
    2045=xx
    Je comprends pas pourquoi il faut que j'appelle alors deux fois mon thread suite à l'ajout de mon reset(). Des idées ?

    La classe comportant ma lecture d'inputstream:
    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    package com.src.ecom.attest.bt;
     
     
     
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
     
    import android.bluetooth.BluetoothSocket;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
     
    public class BufferedThread extends Thread {
     
    	private final BluetoothSocket mmSocket;
    	private final InputStream mmInStream;
    	private final OutputStream mmOutStream;
    	public String msgStatus ="";
    	private int i;
    	private int bytes; // Number of bytes.
    	Handler handler;
     
    	//Getter
    	public String getMsgStatus() {
    		return msgStatus;
    	}
     
    	//Setter
    	public void setMsgStatus(String msgStatus) {
    		this.msgStatus = msgStatus;
    	}
     
    	// Constructeur
    	public BufferedThread(BluetoothSocket socket, Handler h) {
     
    		mmSocket = socket;
    		handler = h;
    		InputStream tmpIn = null;
    		OutputStream tmpOut = null;
    		i=0;
     
    		// Get the input and output streams, using temp objects because
    		// member streams are final
    		try {
    			tmpIn = socket.getInputStream();
    			tmpOut = socket.getOutputStream();
    		} catch (IOException e) { }
     
    		mmInStream = tmpIn;
    		mmOutStream = tmpOut;
    	}
     
    	public void run() {
     
    		byte[] buffer = new byte[2048]; // Read 2K character at a time.
    		bytes= 0;
     
    		while(true)
    		{
    			try
    			{
    				if(mmInStream.available() > 0)
    				{
    					// Read from the InputStream.
    					bytes = mmInStream.read(buffer,0,2048);
    					// Send the obtained bytes to the MainActivity.
    					handler.obtainMessage(InterfaceActivity.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
    					mmInStream.reset();
    				}
    			}
    			catch(IOException e)
    			{
    				msgStatus = e.toString();
    				break;
    			}
    		}           
     
    	}
     
    	/* Call this from the main activity to send data to the remote device */
    	public void write(byte[] bytes) {
    		try {
    			mmOutStream.write(bytes);
    			msgStatus = "Message Envoyé";
    		} catch (IOException e) {
    			msgStatus = e.toString();
    		}
    	}
     
    	/* Call this from the main activity to shutdown the connection */
    	public void cancel() {
    		try {
    			mmSocket.close();
    			msgStatus ="Déconnecté";
    		} catch (IOException e) { 
    			msgStatus = e.toString();
    		}
    	}
    }
    Merci !!!

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 121
    Billets dans le blog
    148
    Par défaut
    Bonjour,

    Faire un reset sur le Stream d'un socket me fait un peu mal. Sachant que au final, le Stream d'une socket, c'est à considérer comme un buffer, qui avance toujours (une pile au final). Enfin, peut être que je me trompe totalement.

    Pour ce qui est du bluetooth, est ce qu'il est garanti que les packets arrivent dans l'ordre (un peu comme dans le cas de l'UDP ?)
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 57
    Par défaut
    Oui pour moi aussi le reset() n'est pas forcement une solution optimale... Faut je trouve une solution similaire je pense mais je bute pour l'instant.

    Pour l'ordre, oui c'est toujours dans le même ordre. C'est juste la façon de lire dans le buffer, la preuve quand je rappelle ma fonction j'ai le reste des données dans l'ordre. J'ai testé une bonne dizaine de fois et c'est dans le même ordre.

  4. #4
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    quelque chose me titille à la lecture de ton code. Rien ne garanti que inputStream va remplir ton buffer, c'est à toi de gérer la popotte. Donc tu connecte la socket, tu lance un thread en attendre de données et hop, dès le premier byte, la socket répond à inputstream. Mais elle n'a qu'un byte pour le moment, donc elle envoie ça. Ensuite, elle avance à l'appel suivant.

    Bref, tu a l'air de considérer que chaque appel à read() te retourner un paquet de données consistant, mais ce n'est pas garanti, le même paquet peux être coupé en deux ou deux paquets peuvent être dans le meme read. Tout dépend de la quantité de données disponibles au moment de l'appel à read et de la taill du byte[]

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 57
    Par défaut
    Donc si je comprends bien il faut que j'ajoute une vérification sur la lecture de mon buffer. Mais cette vérification doit regarder quoi ? S'il y a bien un byte au minimum à renvoyer ?

    La fonction Available() n'est pas suffisante?

    Hier sur le Chat, on m'a donné une hypothèse que peut être que vu que je reçois toujours mes données en deux fois, il se peut qu'entre les deux le read() n'a pas de données et renvoye un 0, ce qui pourrait créer le décalage. C'est la même idée que la tienne ?

    Merci !

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2009
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Octobre 2009
    Messages : 57
    Par défaut
    Bonjour,

    Problème résolu depuis vendredi dernier. Je suis passé au final par un AsyncTask qui permet de lancer des tâches en arrière plan spécifiquement pour Android. Du coup son fonctionnement me permet en partie de résoudre le soucis.
    J'ai aussi ajouté ces conditions qui permettent d'attendre la totalité du message :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    while (-1 != (bytes = mmInStream.read(buffer))) {
    					curMsg.append(new String(buffer, 0, bytes, Charset.forName("UTF-8")));
    					int endIdx = curMsg.indexOf(end);
    					if (endIdx != -1) {
    						String fullMessage = curMsg.substring(0, endIdx + end.length());
    						curMsg.delete(0, endIdx + end.length());
    						// Now send fullMessage
    						return fullMessage;
    					}
    				}

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

Discussions similaires

  1. [PERL] Problème lecture/écriture dans un fichier
    Par LE NEINDRE dans le forum Langage
    Réponses: 4
    Dernier message: 17/08/2005, 13h15
  2. [SAX] Problème lecture fichier xml
    Par BernardT dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 07/07/2005, 18h11
  3. [communication série] problème lecture/écriture
    Par davinout dans le forum API, COM et SDKs
    Réponses: 9
    Dernier message: 01/06/2005, 13h14
  4. Problème lecture fichier en C++
    Par cali1983 dans le forum C++
    Réponses: 17
    Dernier message: 20/05/2005, 09h36
  5. Problème lecture de nombre dans un fichier en c++
    Par knecmotet dans le forum C++
    Réponses: 1
    Dernier message: 28/10/2004, 15h48

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