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 :

Sockets et autres joyeusetés.


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
    IT in outer space
    Inscrit en
    Novembre 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : IT in outer space

    Informations forums :
    Inscription : Novembre 2006
    Messages : 88
    Par défaut Sockets et autres joyeusetés.
    Bonjour,
    je suis en train de tenter une petite appli toute simple pour comprendre les sockets et les threads en Java. J'ai lu quelques docs, consulté des exemples, etc... j'avais réussi à obtenir une communication dans une appli en mode terminal (un autre code que celui que je vais présenter ici qui est repensé).

    J'ai un package serveur dans lequel je souhaite écrire un serveur et un package client pas encore touché. Faisons déjà marcher le côté serveur. Je vais donc me concentrer sur ce package. Celui-ci contient au moment où j'écris 2 classes (je parle des fichiers Java en fait).
    Une classe SocketServeur qui contient le main() et affiche un GUI et une classe SocketServeurMethods dans laquelle j'ai voulu écrire mes fonctions de gestion des sockets. Je ne suis pas sur qu'il soit nécessaire de vous montrer tout le code de la première vu qu'il n'y a rien de spécial donc je m'en tiendrais au main() (au besoin demandez mais c'est rien de plus que ce que Eclipse ajoute pour créer les contrôle genre boutons, zones de texte, etc...) En revanche la classe SocketServeurMethods sera complète.

    SocketServeur.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    SocketServeur application = new SocketServeur();
                    application.getJFrame().setVisible(true);
                }
            });
     
            SocketServeurMethods SSM = new SocketServeurMethods(5020);
            new Thread(SSM).start();
        }
    Tout ce que j'ai fais pour le moment c'est lancer le thread. (2 dernières lignes)

    SocketServeurMethods.java
    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
    package serveur;
     
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
     
    public class SocketServeurMethods implements Runnable 
    {    
        static int port;
        Object obj;
        ServerSocket sv;
     
        SocketServeurMethods() {
            port = 5020;
        }
     
        SocketServeurMethods(int p) {
            port = p;
        }
     
        SocketServeurMethods(int p, Object o) {
            port = p;
            obj = o;
        }
     
        public void run() {
            //TODO
            try {
                //Socket mySock = CreerSocket();
                //*
                ServerSocket myServSock = new ServerSocket(port);
                Socket mySock = myServSock.accept();
                // DEBUG */
     
                String msg;
     
                while (true)
                {
                    msg = LireSocket(mySock); // Ligne 46
                    System.out.println(msg);
                    Thread.sleep(500);
                    if (msg.equals("QUIT"))
                        break;
                }
     
                System.out.println("Closing socket n°"+mySock.toString());
                mySock.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
     
        public Socket CreerSocket () throws IOException {
            ServerSocket sv = new ServerSocket(port);
            Socket s = sv.accept();            
            return s;
        }
     
        public void EcrireSocket (Socket s, String msg) throws IOException {
            OutputStream os = s.getOutputStream();
     
            PrintWriter out = new PrintWriter(
                    new BufferedWriter(
                            new OutputStreamWriter(os)),true);        
            out.println(msg);
            os.close();
        }
     
        public String LireSocket (Socket s) throws IOException {
            InputStream is =s.getInputStream(); //Ligne 81
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(is));
            String msg = in.readLine();
            is.close();
     
            return msg;
        }
    }
    A la base quand j'ai écris ce topic, j'utilisais la ligne commentée (dans run() ) pour obtenir ma socket mais me disant que le problème pouvait venir du fait que je perdais quelque chose dans ma méthode donc j'ai essayé de réécrire tout dans run() mais ça ne change rien.

    Donc premier problème. Quand je me connecte j'ai ceci qui apparait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    java.net.SocketException: Socket is closed
        at java.net.Socket.getInputStream(Socket.java:788)
        at serveur.SocketServeurMethods.LireSocket(SocketServeurMethods.java:81)
        at serveur.SocketServeurMethods.run(SocketServeurMethods.java:46)
        at java.lang.Thread.run(Thread.java:619)
    Ma socket est fermée ? Pourquoi ça ?

    Deuxième petit problème :
    J'aimerais éviter de devoir utiliser la clause throws. En fait à la base je voulais entourer les différents objets par un bloc try/catch comme ça à l'utilisation plus besoin de gérer les exceptions qui seraient alors gérées localement aux méthodes mais il semble qu'il y est un problème de visibilité avec les bloc try/catch. Par exemple, en prenant ma méthode LireSocket() il me serait impossible de retourner mon String msg avec une clause return. Est-ce qu'il y a un moyen d'utiliser une variable incluse dans un bloc try/catch pour l'utiliser en dehors du bloc ?

    Troisième petite problème :
    Ma classe principale implémente une interface graphique. J'avais fait un essai infructueux avant de recommencer depuis le début (ce dont je parlais. Le socket marchait mais en fait je n'avais que le retour dans la console et l'affichage des textes ne se faisaient qu'après avoir terminé avec le socket mais celui-ci n'était pas écris dans un thread à part)
    Je voudrais trouver un moyen de rediriger mes messages vers un contrôle au choix. L'idée se développe un peu dans le troisième constructeur de la classe ServeurSocketMethods où j'ai pensé mettre un objet en second argument pour pouvoir faire des traitements dessus à partir de ma classe mais je ne sais pas si c'est la bonne approche du problème.
    Je vais vous expliquer ce que j'ai en tête si vous avez besoin d'un exemple.
    Ma classe Socket Serveur crée une IHM "graphique" qui comme toute IHM de ce type contient divers contrôles. L'idée était de pouvoir choisir vers quel contrôle écrire mes lignes de texte. Donc j'aurais pu déclarer des choses dans le genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SocketServeurMethods SSM1(2055, Textarea1);
    SocketServeurMethods SSM2(5022, Textarea2);
    Par contre l'objet Object est un peu trop général pour me proposer des méthodes comme append() ou setText() mais passer un JTextField, un JTextArea, un JEditorPane ou un JTextPane rendrait trop spécifique la classe. Dans ce que je fais ça n'est pas trop grave mais on peut rencontrer ce genre de situation qui serait alors problématique.

    Quatrième petit problème :
    Cette fois c'est au niveau des threads. Comment travailler avec une classe dont on a lancé un thread ? Je veux dire comment utiliser ses attributs/méthodes publiques quand on a pas de point d'entrée. Ici je n'ai pas trop d'exemple mais j'ai eu un cas comme ça mais bon je n'ai pas d'exemple concret a montrer. Disons que j'avais vu un code qui lance un thread à partir d'un objet mais je ne savais pas comment profiter de ses éléments. Si ça parle à quelqu'un expliquez moi sinon ignorer ce quatrième point.

    Je vous remercie pour votre patience et j'espère qu'on pourra m'aider dans mon problème. Merci.

  2. #2
    Membre expérimenté Avatar de Roy Miro
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    273
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 273
    Par défaut
    Est-ce qu'il y a un moyen d'utiliser une variable incluse dans un bloc try/catch pour l'utiliser en dehors du bloc ?
    Bonjour,
    tu peux déclarer une variable en dehors du try/catch, comme ça elle sera visible en dehors du bloc.

    Pour le problème de socket fermée, je pensais avoir trouvé mais non

    Bon courage

  3. #3
    Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 8
    Par défaut
    C'est quoi le code de l'application cliente?

  4. #4
    Membre confirmé
    Homme Profil pro
    IT in outer space
    Inscrit en
    Novembre 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : IT in outer space

    Informations forums :
    Inscription : Novembre 2006
    Messages : 88
    Par défaut
    Bonjour,
    merci pour vos réponses.

    Pour ce qui est du try/catch au départ j'avais quelque chose 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
    18
     
        public String LireSocket (Socket s) {
            InputStream is = null;
        Sting msg = null;
        try
        {
            s.getInputStream(); //Ligne 81
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(is));
                msg = in.readLine();
                is.close();
        } catch (IOException e)
        {
            e.PrintStackTrace();
        }
     
            return msg;
        }
    Effectivement, tout semblait bien se passer mais j'avais un doute sur la visibilité de ma variable.
    Pour être honnête je n'ai pas testé le code,étant convaincu qu'en fait ma variable garderait la valeur null.
    Je sais ce qui me reste à faire pour ce point.

    Pour le client. Comme j' l'ai dis, je verrais plus tard. Pour le moment je teste avec un client Telnet tout simplement.

    Roy Miro, dites moi ce que vous aviez en tête, ça pourrait peut-être me mettre sur une piste même si en soi ça n'est pas la solution.

    EDIT:
    Si je réécris la méthode de la manière dont je parles j'obtiens ceci.
    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
        public String LireSocket (Socket s) {
            InputStream is = null;
            try {
                is = s.getInputStream();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(is));
            String msg;
            try {
                msg = in.readLine();
                is.close();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
     
            return msg;
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    The local variable msg may not have been initialized
    C'est pour ça que je pense qu'il y a une visibilité particulière avec les blocs try/catch et je ne vois pas comment renvoyer ma chaine en retour dans ce cas.

    D'après certaines recherches (Google -> try catch return) il semblerait qu'on peut faire quelque chose que je n'imaginais même pas...
    Mettre une clause return à la fin du bloc try.
    J'ai plusieurs idées différentes sur le fonctionnement de cette clause. Il va falloir que je me renseigne un peu.

  5. #5
    Membre très actif
    Inscrit en
    Mars 2008
    Messages
    283
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 283
    Par défaut
    Citation Envoyé par Pasokoniidesuka Voir le message
    Bonjour,
    merci pour vos réponses.

    Pour ce qui est du try/catch au départ j'avais quelque chose 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
    18
     
        public String LireSocket (Socket s) {
            InputStream is = null;
        Sting msg = null;
        try
        {
            s.getInputStream(); //Ligne 81
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(is));
                msg = in.readLine();
                is.close();
        } catch (IOException e)
        {
            e.PrintStackTrace();
        }
     
            return msg;
        }
    Effectivement, tout semblait bien se passer mais j'avais un doute sur la visibilité de ma variable.
    Pour être honnête je n'ai pas testé le code,étant convaincu qu'en fait ma variable garderait la valeur null.
    Je sais ce qui me reste à faire pour ce point.

    Pour le client. Comme j' l'ai dis, je verrais plus tard. Pour le moment je teste avec un client Telnet tout simplement.

    Roy Miro, dites moi ce que vous aviez en tête, ça pourrait peut-être me mettre sur une piste même si en soi ça n'est pas la solution.

    EDIT:
    Si je réécris la méthode de la manière dont je parles j'obtiens ceci.
    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
        public String LireSocket (Socket s) {
            InputStream is = null;
            try {
                is = s.getInputStream();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(is));
            String msg;
            try {
                msg = in.readLine();
                is.close();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
     
            return msg;
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    The local variable msg may not have been initialized
    C'est pour ça que je pense qu'il y a une visibilité particulière avec les blocs try/catch et je ne vois pas comment renvoyer ma chaine en retour dans ce cas.

    D'après certaines recherches (Google -> try catch return) il semblerait qu'on peut faire quelque chose que je n'imaginais même pas...
    Mettre une clause return à la fin du bloc try.
    J'ai plusieurs idées différentes sur le fonctionnement de cette clause. Il va falloir que je me renseigne un peu.
    Pour la socket fermée, c'est anormal, je n'arrive pas à voir le problème.

    Pour l'erreur de variable locale pas initialisée, il faut mettre msg à null à la déclaration. Certes on dit que c'est déjà le raisonnement de la JVM le plus courant, mais ce n'est pas nécessairement vrai.
    Pour t'expliquer l'origine du problème, c'est simple. Une exception peux venir à la ligne "msg = in.readLine();". Si tel est le cas, on entre dans le catch et msg est toujours sans valeur.

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    342
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 342
    Par défaut
    alors j'ai une réponse a t'a 1er question

    a la fin de LireSocket tu fait is.close(); ce qui fait que ton programme ferme le flux qui est sur is ( ta socket ) donc quand tu relance LireSocket ta socket est fermer.

    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
        public void run() {
            //TODO
            try {
                //Socket mySock = CreerSocket();
                //*
                ServerSocket myServSock = new ServerSocket(port);
                Socket mySock = myServSock.accept();
                // DEBUG */
     
                String msg;
     
                InputStream is = mySock.getInputStream();
                BufferedReader in = new BufferedReader(new InputStreamReader(is));
     
     
                while (true) {
     
                    msg = in.readLine();
                    System.out.println(msg);
                    Thread.sleep(500);
                    if (msg.equals("QUIT")) {
                        break;
                    }
                }
     
                System.out.println("Closing socket n°" + mySock.toString());
                mySock.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    pour lire t'a Socket dans ce cas la mysock.close() fermera les autre stream

Discussions similaires

  1. [FocusTraversalPolicy] et autres joyeusetés
    Par Ofunk dans le forum Interfaces Graphiques en Java
    Réponses: 2
    Dernier message: 17/06/2010, 13h35
  2. Réponses: 6
    Dernier message: 14/10/2008, 00h37
  3. Style et autres joyeusetés pour faire un menu en expander
    Par Harpist dans le forum Windows Presentation Foundation
    Réponses: 4
    Dernier message: 19/06/2008, 14h22
  4. Vista , admin , UAC , et autres joyeusetés
    Par boulbi dans le forum EDI
    Réponses: 18
    Dernier message: 29/10/2007, 17h17
  5. Réponses: 5
    Dernier message: 18/10/2006, 20h30

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