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 :

BufferedReader readline bloquant


Sujet :

Entrée/Sortie Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 39
    Par défaut BufferedReader readline bloquant
    Bonjour,

    Après avoir effectuer des recherches sur notre ami Google toujours pas de réponse à mon problème.

    Je réalise une application Lambda client-serveur et pour lancer une instance de Lambda, il me faut deux clients. Donc à un moment donné le client 1 doit être en phase d'attente jusqu'à ce qu'un deuxième client se connecte sur le serveur.

    Voila mon code serveur:
    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
     
    ServerSocket serveur;
    InetAddress adresse_serveur;
    int port_serveur;
     
    serveur = new ServerSocket(8000);
    adresse_serveur = InetAddress.getLocalHost();
    port_serveur = serveur.getLocalPort();
     
    System.out.println("Serveur Lambda démarré...");
    System.out.println("L'adresse du serveur est: "+adresse_serveur.getHostAddress());
    System.out.println("Le port du serveur est: "+port_serveur);
     
    while (true)
    {
    	Socket clientSocket1, clientSocket2;
     
    	clientSocket1 = serveur.accept();
    	System.out.println("Connexion réussi pour 1er client");
     
    	clientSocket2 = serveur.accept();
    	System.out.println("Connexion réussi pour 2nd client");
     
    	PartieLambda partie = new PartieLambda( clientSocket1, clientSocket2);
           System.out.println("nouvelle partie créée");
     
    }
    Au niveau du client, celui ci ouvre un formulaire de connexion et renseigner son nom, le serveur et le port de connexion.

    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
     
    BufferedReader  fluxEntrant;
     
    Socket socket = null;
    int port_serveur = Integer.parseInt(port);
     
    InetAddress adresse_serveur = InetAddress.getByName(serveur);
    socket = new Socket( adresse_serveur, port_serveur); 
    System.out.println("socket connecté : " + socket.getLocalPort());
     
    f.setVisible(false); // On ferme la fênetre active (le formulaire)
    attente = new FenetreAttente("Morpion"); // On ouvre une fênetre avec un sablier en gif + un texte "Attente du client n°2
     
     
    fluxEntrant = new BufferedReader(new InputStreamReader( socket.getInputStream()));
    System.out.print("attente signal début du serveur : ");
    String signal = fluxEntrant.readLine();
    System.out.println(signal);
    Le soucis est que le readLine() (avant dernière ligne) est bloquant. Vous me direz c'est normal c'est un peu son rôle et d'ailleurs c'est ce que je souhaite car j'attends que le serveur me dises "Oui c'est bon, il y a deux clients". (cela se fait durant le:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     PartieLambda partie = new PartieLambda( clientSocket1, clientSocket2);
    Le problème c'est que la fenêtre client (avec le gif et le texte) est buggée, elle apparait transparente et n'affichant ni le gif ni le texte. Tout redevient normal lorsque le 2eme client est connecté et que l'on a passé le readLine()

    Bilan: Comment faire pour que readLine ne soit pas bloquant au niveau de ma fênetre graphique ?

    Merci de votre aide d'avance.

  2. #2
    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 : 45
    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
    Citation Envoyé par piscou51000 Voir le message
    Le problème c'est que la fenêtre client (avec le gif et le texte) est buggée, elle apparait transparente et n'affichant ni le gif ni le texte. Tout redevient normal lorsque le 2eme client est connecté et que l'on a passé le readLine()

    Bilan: Comment faire pour que readLine ne soit pas bloquant au niveau de ma fênetre graphique ?

    Merci de votre aide d'avance.
    C'est probablement parce que tu fait ton readLine dans le Thread de l'EDT. Il ne faut pas faire d'opération longue ou bloquante dans l'EDT.


    voilà une petite doc pour commencer http://gfx.developpez.com/tutoriel/j...ing-threading/

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 39
    Par défaut
    Merci de ta réponse,

    Je vais étudier en profondeur le lien que tu m'as fourni et faire un mix avec celui-ci.

    Je vous tiens au courant de mon avancement. Même si ça me parait compliquer tous ça comparé à mon niveau de débutant. Mais bon jamais rien n'est insurmontable.

    Bonne soirée..

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 39
    Par défaut
    Je reviens vers vous plus amples informations.

    Donc si je comprends bien le problème vient du fait que l'affichage de ma fenêtre et l'attente de la réponse serveur (readLine()) se passe dans le même Thread.

    Toujours si je comprends bien: il faudrait donc que j'utilise la classe SwingWorker afin de pouvoir externaliser l'un des deux travaux. Vous me conseillerez d'externaliser l'affichage de ma fenêtre ou readLine().

    Merci de vos réponse.

  5. #5
    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 : 45
    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
    avec le readline, tu bloque le thread d'affichage, donc il faut faire le readline ailleurs. On ne fait aucune mise à jour de l'interface graphique en dehors de l'EDT! donc ce n'est pas ta mise à jour de fenetre à retirer. la classe swingworker est bien expliquée ici:

    http://rom.developpez.com/java-swingworker/

    Principe de base du swingworker: faire du travail long dans un thread en background et, à la fin, réinvoker l'edt pour faire la mise à jour de l'affichage.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 39
    Par défaut Ma solution..
    Donc voila, je vous montre ma solution. tchize_ si tu repasses par là pourrait tu me donner ton avis sur ma solution. Merci d'avance.

    Alors, j'ai créer ma propre classe qui hérite de SwingWorker. Voici le code:

    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
     
    // Je vous fait grâce des import 
     
    class SwingWorkerEcouteur extends SwingWorker<Integer, String> {
     
    	BufferedReader  fluxEntrant;
    	Socket s;
    	public SwingWorkerEcouteur(Socket s) {
    		this.s = s;
        }
     
        @Override
        public Integer doInBackground() {
        	try {
    			fluxEntrant = new BufferedReader(new InputStreamReader( this.s.getInputStream()));
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
     
        		System.out.print("attente signal début du serveur : ");
     
        		String signal = null;
    			try {
    				signal = fluxEntrant.readLine();
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
        		System.out.println(signal);
        	return 0;
        }
     
        @Override
        protected void process(List<String> strings) {
           // Je n'ai rien à faire ici dans mon cas
        }
     
        @Override
        protected void done() {
           // Ce qu'il faut faire après le readLine()...
        }
    }
    J'appelle ce code grâce à:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    		SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    /* Démarrage de l'interface graphique et du SwingWorker. */
                    SwingWorkerEcouteur demo = new SwingWorkerEcouteur(socket);
                    demo.execute();
                }
            });
    Si ça peut aider un jour quelqu'un...

    Merci en tout cas de tes réponses tchize_ qui m'ont vraiment très bien orienté.

    Bonne journée..

  7. #7
    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 : 45
    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
    invokelater sert à demander swing de faire quelque chose plus tard. La, dans ton code, tu demande à swing de 'plus tard' exécuter un petit code dont le seul job sera de démarrer un nouveau thread pour le swingworker. Tu peux simplifier en lancant le swingworker immédiatement (la méthode execute a pour seul role de mettre en tache de fond le worker). En pratique, pour ton cas, comme ton thread n'update pas l'interface graphique tu n'aurais, théoriquement, pas besoin de swingworker, mais je le garderais quand même parce que rien ne dit que plus tard tu n'aura pas besoin de mettre à jour l'ui.

    Donc pour résumer, tu garde ton worker mais tu remplace le deuxième code par, tout simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    new SwingWorkerEcouteur(socket).execute();

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 39
    Par défaut
    Ok merci pour tes conseils.

    Je met le post en Résolu.

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

Discussions similaires

  1. BufferedReader readLine() ne s'arrête jamais
    Par jadey dans le forum Entrée/Sortie
    Réponses: 12
    Dernier message: 26/03/2014, 18h20
  2. While + BufferedReader + readLine() = manque la dernière ligne
    Par JulianMarley dans le forum Débuter avec Java
    Réponses: 7
    Dernier message: 25/11/2013, 14h49
  3. BufferedReader readLine() :(
    Par javan00b dans le forum Entrée/Sortie
    Réponses: 2
    Dernier message: 29/08/2009, 21h38
  4. ReadLine bloquant sur un socket
    Par Hellnino18 dans le forum Entrée/Sortie
    Réponses: 12
    Dernier message: 17/03/2009, 10h37
  5. BufferedReader + ReadLine()
    Par mimil dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 21/05/2005, 20h01

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