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

  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

  7. #7
    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
    C'est un peu bizarre parce que il n'est pas sensé sortir de la boucle while tant que le message transmis dans la socket est différent de "QUIT". Et pour pas coder comme un port on ferme la ressource quand elle ne sert plus à rien.

    Mais bon le code a un peu changé depuis et il me pose un autre problème. Je ne sais pas si le problème de socket fermé serait résolu après ça ou pas mais

    La nouvelle mode c'est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    java.net.BindException: Address already in use: JVM_Bind
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:365)
        at java.net.ServerSocket.bind(ServerSocket.java:319)
        at java.net.ServerSocket.<init>(ServerSocket.java:185)
        at java.net.ServerSocket.<init>(ServerSocket.java:97)
        at serveur.SocketServeurMethods.CreerSocket(SocketServeurMethods.java:71)
        at serveur.SocketServeurMethods.run(SocketServeurMethods.java:35)
        at java.lang.Thread.run(Thread.java:619)
    Exception in thread "Thread-2" java.lang.NullPointerException
        at serveur.SocketServeurMethods.LireSocket(SocketServeurMethods.java:109)
        at serveur.SocketServeurMethods.run(SocketServeurMethods.java:45)
        at java.lang.Thread.run(Thread.java:619)
    Je crois avoir ma petite idée sur la raison du socket déjà utilisé mais je ne vois pas comment le contourner.
    Au moment où j'avais écris cette fonction j'ai considéré mon objet Socket comme un Int qui "disparait" une fois la méthode terminée. J'ai donc peut-être eu une mauvaise approche du problème.

    Sinon je viens de tomber sur un tuto qui m'a l'air très intéressant.
    Je vais le lire et voir ce qui va pas dans ma manière de faire.

  8. #8
    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
    je viens de survolé le tuto et c'est plutôt pas mal expliqué

  9. #9
    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
    Je crois que je viens d'ouvrir les yeux sur un truc... J'y ais pas fait attention mais mon main est inclus dans une classe. Ca me change du C où j'écris mon main à part directement sans pour autant que ce soit inclus dans une classe. D'ailleurs je trouve cette manière de faire "inhabituelle" à mon niveau.

    J'ai essayé d'appliquer le tuto et ça semble marcher en partie. En fait mon thread se lance et j'ai bien pu connecter plusieurs clients (toujours en telnet pour le moment) mais j'ai un souci au niveau de l'interaction avec l'interface graphique. Je suis convaincu que le problème est liée aux threads (y'a que ça de toute façon) En fait quand j'ai testé mon code il n'y avait pas d'interface graphique mais j'avais les réponses sur la console Eclipse et ça marchait bien hormis peut-être un petit souci d'encodage mais ça on verras plus tard...
    Je mets une copie d'écran pour vous montrer. En fait l'interface graphique semble "bloquée", elle ne se met pas à jour.

    Je pense que tout doit se jouer dans le main. Mais bon j'ai pas trop le choix si je veux profiter de ma classe je dois l'instancier dans le main. A part le fait de pouvoir déplacer le rebord de fenêtre et de minimiser rien ne marche. je suis obligé de terminer le programme depuis Eclipse à l'aide du bouton stop.

    Je remet mes classes mises-à-jour.
    SocketServeur.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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    package serveur;
     
    import java.awt.event.KeyEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    import java.awt.Event;
    import java.awt.BorderLayout;
    import javax.swing.SwingConstants;
    import javax.swing.SwingUtilities;
    import javax.swing.KeyStroke;
    import java.awt.Point;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JMenuItem;
    import javax.swing.JMenuBar;
    import javax.swing.JMenu;
    import javax.swing.JFrame;
    import javax.swing.JDialog;
    import javax.swing.JTextField;
    import java.awt.Rectangle;
    import javax.swing.JTextArea;
    import javax.swing.JScrollPane;
    import javax.swing.JButton;
     
    public class SocketServeur {
     
        private JFrame jFrame = null;  //  @jve:decl-index=0:visual-constraint="11,9"
        private JPanel jContentPane = null;
        private JMenuBar jJMenuBar = null;
        private JMenu fileMenu = null;
        private JMenu editMenu = null;
        private JMenu helpMenu = null;
        private JMenuItem exitMenuItem = null;
        private JMenuItem aboutMenuItem = null;
        private JMenuItem cutMenuItem = null;
        private JMenuItem copyMenuItem = null;
        private JMenuItem pasteMenuItem = null;
        private JMenuItem saveMenuItem = null;
        private JDialog aboutDialog = null;
        private JPanel aboutContentPane = null;
        private JLabel aboutVersionLabel = null;
        private JTextField jTextField = null;
        private JTextArea jmyTextArea = null;
        private JScrollPane jScrollPane = null;
        private JButton jButton = null;
     
        /**
         * This method initializes jTextField    
         *     
         * @return javax.swing.JTextField    
         */
        private JTextField getJTextField() {
            if (jTextField == null) {
                jTextField = new JTextField();
                jTextField.setBounds(new Rectangle(8, 120, 249, 20));
            }
            return jTextField;
        }
     
        /**
         * This method initializes jmyTextArea    
         *     
         * @return javax.swing.JTextArea    
         */
        private JTextArea getJmyTextArea() {
            if (jmyTextArea == null) {
                jmyTextArea = new JTextArea();
                jmyTextArea.setRows(5);
                jmyTextArea.setWrapStyleWord(true);
                jmyTextArea.setLineWrap(true);
            }
            return jmyTextArea;
        }
     
        /**
         * This method initializes jScrollPane    
         *     
         * @return javax.swing.JScrollPane    
         */
        private JScrollPane getJScrollPane() {
            if (jScrollPane == null) {
                jScrollPane = new JScrollPane();
                jScrollPane.setBounds(new Rectangle(8, 8, 249, 113));
                jScrollPane.setViewportView(getJmyTextArea());
            }
            return jScrollPane;
        }
     
        /**
         * This method initializes jButton    
         *     
         * @return javax.swing.JButton    
         */
        private JButton getJButton() {
            if (jButton == null) {
                jButton = new JButton();
                jButton.setBounds(new Rectangle(256, 120, 57, 17));
                jButton.setText("OK");
            }
            return jButton;
        }
     
    // LE MAIN EST ICI !!!!
        /**
         * @param args
         */
        public static void main(String[] args) {
            SwingUtilities.invokeLater(
                    new Runnable() {
                        public void run() {
                            SocketServeur application = new SocketServeur();
                            //TODO Passer jmyTextArea en premier paramètre
                            application.getJFrame().setVisible(true);
                            SocketServeurMethods SSM = new SocketServeurMethods(application.jmyTextArea, 5020);
                            SSM.CreerSocket();
                        }
                    }
            );
            // Au début je voulais démarrer mon thread ici mais j'ai pas réussi. :(
        }
     
        /**
         * This method initializes jFrame
         * 
         * @return javax.swing.JFrame
         */
        private JFrame getJFrame() {
            if (jFrame == null) {
                jFrame = new JFrame();
                jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                jFrame.setJMenuBar(getJJMenuBar());
                jFrame.setSize(330, 200);
                jFrame.setContentPane(getJContentPane());
                jFrame.setTitle("Application");
            }
            return jFrame;
        }
     
        /**
         * This method initializes jContentPane
         * 
         * @return javax.swing.JPanel
         */
        private JPanel getJContentPane() {
            if (jContentPane == null) {
                jContentPane = new JPanel();
                jContentPane.setLayout(null);
                jContentPane.add(getJTextField(), null);
                jContentPane.add(getJScrollPane(), null);
                jContentPane.add(getJButton(), null);
            }
            return jContentPane;
        }
     
        /**
         * This method initializes jJMenuBar    
         *     
         * @return javax.swing.JMenuBar    
         */
        private JMenuBar getJJMenuBar() {
            if (jJMenuBar == null) {
                jJMenuBar = new JMenuBar();
                jJMenuBar.add(getFileMenu());
                jJMenuBar.add(getEditMenu());
                jJMenuBar.add(getHelpMenu());
            }
            return jJMenuBar;
        }
     
        /**
         * This method initializes jMenu    
         *     
         * @return javax.swing.JMenu    
         */
        private JMenu getFileMenu() {
            if (fileMenu == null) {
                fileMenu = new JMenu();
                fileMenu.setText("File");
                fileMenu.add(getSaveMenuItem());
                fileMenu.add(getExitMenuItem());
            }
            return fileMenu;
        }
     
        /**
         * This method initializes jMenu    
         *     
         * @return javax.swing.JMenu    
         */
        private JMenu getEditMenu() {
            if (editMenu == null) {
                editMenu = new JMenu();
                editMenu.setText("Edit");
                editMenu.add(getCutMenuItem());
                editMenu.add(getCopyMenuItem());
                editMenu.add(getPasteMenuItem());
            }
            return editMenu;
        }
     
        /**
         * This method initializes jMenu    
         *     
         * @return javax.swing.JMenu    
         */
        private JMenu getHelpMenu() {
            if (helpMenu == null) {
                helpMenu = new JMenu();
                helpMenu.setText("Help");
                helpMenu.add(getAboutMenuItem());
            }
            return helpMenu;
        }
     
        /**
         * This method initializes jMenuItem    
         *     
         * @return javax.swing.JMenuItem    
         */
        private JMenuItem getExitMenuItem() {
            if (exitMenuItem == null) {
                exitMenuItem = new JMenuItem();
                exitMenuItem.setText("Exit");
                exitMenuItem.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        System.exit(0);
                    }
                });
            }
            return exitMenuItem;
        }
     
        /**
         * This method initializes jMenuItem    
         *     
         * @return javax.swing.JMenuItem    
         */
        private JMenuItem getAboutMenuItem() {
            if (aboutMenuItem == null) {
                aboutMenuItem = new JMenuItem();
                aboutMenuItem.setText("About");
                aboutMenuItem.addActionListener(
                        new ActionListener() {
                            public void actionPerformed(ActionEvent e) {
                                JDialog aboutDialog = getAboutDialog();
                                aboutDialog.pack();
                                Point loc = getJFrame().getLocation();
                                loc.translate(20, 20);
                                aboutDialog.setLocation(loc);
                                aboutDialog.setVisible(true);
                            }
                        }
                );
            }
            return aboutMenuItem;
        }
     
        /**
         * This method initializes aboutDialog    
         *     
         * @return javax.swing.JDialog
         */
        private JDialog getAboutDialog() {
            if (aboutDialog == null) {
                aboutDialog = new JDialog(getJFrame(), true);
                aboutDialog.setTitle("About");
                aboutDialog.setContentPane(getAboutContentPane());
            }
            return aboutDialog;
        }
     
        /**
         * This method initializes aboutContentPane
         * 
         * @return javax.swing.JPanel
         */
        private JPanel getAboutContentPane() {
            if (aboutContentPane == null) {
                aboutContentPane = new JPanel();
                aboutContentPane.setLayout(new BorderLayout());
                aboutContentPane.add(getAboutVersionLabel(), BorderLayout.CENTER);
            }
            return aboutContentPane;
        }
     
        /**
         * This method initializes aboutVersionLabel    
         *     
         * @return javax.swing.JLabel    
         */
        private JLabel getAboutVersionLabel() {
            if (aboutVersionLabel == null) {
                aboutVersionLabel = new JLabel();
                aboutVersionLabel.setText("Version 1.0");
                aboutVersionLabel.setHorizontalAlignment(SwingConstants.CENTER);
            }
            return aboutVersionLabel;
        }
     
        /**
         * This method initializes jMenuItem    
         *     
         * @return javax.swing.JMenuItem    
         */
        private JMenuItem getCutMenuItem() {
            if (cutMenuItem == null) {
                cutMenuItem = new JMenuItem();
                cutMenuItem.setText("Cut");
                cutMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,
                        Event.CTRL_MASK, true));
            }
            return cutMenuItem;
        }
     
        /**
         * This method initializes jMenuItem    
         *     
         * @return javax.swing.JMenuItem    
         */
        private JMenuItem getCopyMenuItem() {
            if (copyMenuItem == null) {
                copyMenuItem = new JMenuItem();
                copyMenuItem.setText("Copy");
                copyMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
                        Event.CTRL_MASK, true));
            }
            return copyMenuItem;
        }
     
        /**
         * This method initializes jMenuItem    
         *     
         * @return javax.swing.JMenuItem    
         */
        private JMenuItem getPasteMenuItem() {
            if (pasteMenuItem == null) {
                pasteMenuItem = new JMenuItem();
                pasteMenuItem.setText("Paste");
                pasteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,
                        Event.CTRL_MASK, true));
            }
            return pasteMenuItem;
        }
     
        /**
         * This method initializes jMenuItem    
         *     
         * @return javax.swing.JMenuItem    
         */
        private JMenuItem getSaveMenuItem() {
            if (saveMenuItem == null) {
                saveMenuItem = new JMenuItem();
                saveMenuItem.setText("Save");
                saveMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
                        Event.CTRL_MASK, true));
            }
            return saveMenuItem;
        }
     
    }
    ServeurSocketMethods.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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    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;
     
    import javax.swing.JTextArea;
     
    class InstanceClient implements Runnable{
        private Socket cliSock = null;
        private JTextArea vTextArea = null;
        private InputStream is = null;
        private BufferedReader in = null;
     
     
        InstanceClient(Socket s, JTextArea TextArea) 
        {
            this.cliSock = s;
            this.vTextArea = TextArea;
        }
     
        public void run() {
            String msg;
            // Création d'une Socket + BufferReader pour lire dessus.
            try {
                is = cliSock.getInputStream();
                in = new BufferedReader(new InputStreamReader(is));
            }
            catch (IOException e1) {
                e1.printStackTrace();
            }
     
            // Boucle du thread
            while (true)
            {
                try {
                    msg = in.readLine();
                    System.out.println(msg);
                    Thread.sleep(500);
     
                    // On vérifie la connectivité
                    if (!cliSock.isConnected())
                    {
                        System.out.println("Plus de connectivité !!!");
                        break;
                    }
                    else
                    {
                        // Si tjs connecté
                        try
                        {
                            if (msg.equals("QUIT"))
                                break;
                        } catch (NullPointerException e)
                        {
                            e.getCause();
                            break;
                        }
     
                        if (vTextArea != null)
                        {
                            vTextArea.append(msg+"\n");
                            /*/ Essais au pif xD
                            vTextArea.validate();
                            vTextArea.updateUI(); //DEBUG*/
                        }
                    }
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
     
            System.out.println("Closing socket n°: " + cliSock.toString());
            try {
                is.close();
                in.close();
                cliSock.close();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
     
        }
     
        public void EcrireSocket (Socket s, String msg) {
            OutputStream os = null;
            // Définition OutputStream
            try
            {
                os = s.getOutputStream();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
     
            // Définition flux de sortie
            PrintWriter out = new PrintWriter(
                    new BufferedWriter(
                            new OutputStreamWriter(os)),true);
            // Écriture du message
            out.println(msg);
     
            //Fermeture du flux de sortie
            try {
                os.close();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        /*/
        public String LireSocket (Socket s) {
     
            String msg=null;
            // Definition Input Stream
            try {
                this.is = s.getInputStream();
                this.in = new BufferedReader(
                    new InputStreamReader(is));
                
                // Récupération du message.
                msg = in.readLine();
                System.out.println("pmsg Est-ce que socket est fermée ? : "+s.isClosed());
                //
                is.close();
                System.out.println("pic Est-ce que socket est fermée ? : "+s.isClosed());
                in.close(); //DEBUG /
                System.out.println("pin Est-ce que socket est fermée ? : "+s.isClosed());
                return msg;
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            
            return msg;
        } //*/
    }
     
    public class SocketServeurMethods
    {    
        private static int port;
        private ServerSocket sv;
        private JTextArea jta;
     
     
        SocketServeurMethods(JTextArea jta) {
            this.jta = jta;
            port = 5020;
        }
     
        SocketServeurMethods(JTextArea jta, int p) {
            this.jta = jta;
            port = p;
        }
     
        public void CreerSocket (){
            // Création de la socket du serveur
            try
            {
                sv = new ServerSocket(port);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
     
            // Attente des nouveaux clients.        
            while (true)
            {
                // Création d'une instance d'accueil du client
                InstanceClient ic;
                try{
                    ic = new InstanceClient(sv.accept(), this.jta);
                    Thread t = new Thread(ic);
                    t.start();
                } catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
     
    }
    Voilà. Merci d'avance pour vos conseils et réponses.
    Images attachées Images attachées  

  10. #10
    vic
    vic est déconnecté
    Membre chevronné

    Profil pro
    Inscrit en
    Août 2002
    Messages
    431
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 431
    Par défaut
    Déjà ne poste pas 10 pages de code, essaie un peu d'élaguer pour cerner ce qui pose problème; on n'a pas besoin de lire tout le code d'initialisation de la GUI.

    Le problème est que tu appelles SSM.CreerSocket(); dans SwingUtilities.invokeLater(). Cette méthode ne retourne jamais et donc la thread Swing est bloquée indéfiniment. Il faut réserver SwingUtilities.invokeLater() à l'exécution de tâches courtes liées à la GUI.

    Pour corriger le problème tu peux soit déplacer l'appel de SSM.CreerSocket() dans le main, soit créer une autre thread pour l'exécuter.

  11. #11
    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
    OK mais c'est justement ce que j'avais essayé de faire au début mais comme je l'avais mis en commentaire je n'avais pas réussi.
    En fait ma classe SocketServeur à besoin d'une référence sur le JTextArea mais comme ça ne marche pas en dehors du InvokeLater je l'ai mis dedans.
    En tout cas merci pour les explications.

  12. #12
    vic
    vic est déconnecté
    Membre chevronné

    Profil pro
    Inscrit en
    Août 2002
    Messages
    431
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 431
    Par défaut
    Supprime complètement le SwingUtilities.invokeLater et met ton code directement dans le main.

    En théorie tu devrais mettre le SwingUtilities.invokeLater autour des appels à JTextArea.append() dans InstanceClient, mais comme cette méthode est thread-safe ce n'est pas obligatoire.

  13. #13
    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
    Merci. C'est ce que j'avais fait aujourd'hui et ça marche.
    Seulement je suis tombé sur quelques doc et c'est pas sans raisons qu'on utilise InvokeLater.
    Je ne cite rien que ce tuto
    http://gfx.developpez.com/tutoriel/j...ing-threading/
    http://rom.developpez.com/java-swingworker/ (J'ai essayé ce code qui renvoi une exception pendant l'exécution...)
    Enfin je me pencherais dessus plus tard.
    Mon serveur dispose d'une zone de texte à l'aide de laquelle je souhaitais pouvoir envoyer un message aux clients mais j'ai eu quelques soucis d'ordre méthodologique. Le plus naturellement du monde j'ai voulu éditer la méthode actionPerformed lié au bouton qui doit décider de l'envoi mais je me suis vite rendu compte que je n'avais pas accès à la socket de là.
    Et puis le truc qui est étrange, bien que ça ne soit pas un problème de java, c'est que lors des sessions telnet mon curseur bouge mais je ne vois aucun des caractères que je saisi. xD
    Je vais faire une photo d'écran tiens... c'est plus parlant (cf. images jointes).
    Si quelqu'un saurait par hasard ce qui cause ou peut causer ce comportement, merci de bien vouloir m'en informer.
    Images attachées Images attachées    

  14. #14
    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
    pour ce qui est de telnet c'est normal les caractère affiché sont ceux qui sont ressue par le serveur qui lui vas les renvoyer au client. Le caractère que tu voie afficher n'est pas celui de ton clavier mais celui que le serveur te renvoie.

  15. #15
    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
    Ah bon, c'est bizarre parce que dans un de mes essaies (en mode console) ça marchait mais bon soit, merci de l'explication.

    Sinon j'ai voulu essayer d'utiliser le invokeLater comme prévu par VE et pour créer ma objet SocketServeurMethods j'ai voulu imiter le style de code fait par VE.
    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
     
    	/**
             * @param args
             */
    	public static void main(String[] args) {
    		//
    		SwingUtilities.invokeLater(
    				new Runnable() {
    					public void run() {
    						SocketServeur application = new SocketServeur();
    						application.getJFrame().setVisible(true);
    						application.getSSM(); // Essai 1
    					}
    				}
    		);//DEBUG*/
     
    		/*/
    		SocketServeur application = new SocketServeur();
    		//application.getJFrame().setVisible(true);
    		//DEBUG*/
    	}
     
    	private SocketServeurMethods getSSM(){
    		if (SSM == null){
    			SSM = new SocketServeurMethods(this.getJmyTextArea(), 5020); // Essai 2
    		}
    		return SSM;
    	}
    Si je lance l'appli se lance mais où devrais-je appeler ma méthode CreerSocket ?
    J'ai essayé tout de suite après les lignes commentées Essai 1 et Essai 2. Mais dans les deux cas je retourne sur le problème de l'appli bloquée (photo d'écran dans un précédent post).
    Tel quel, le code marche mais bien sur comme j'ai pas crée ma socket ça ne peut pas marcher.
    Aussi, est-ce que j'ai moyen de tester ma classe SocketServeurMethods à part pour vérifier qu'elle fonctionne bien ?

    EDIT:
    Je me suis un peu renseigné et effectivement il y a bien un système d'echoing qui renvoi les caractères et celui-ci est désactivé localement chez moi. Pour quelle raison ? Je n'en sais rien. Je vais voir comment le réactiver.

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