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
Tout ce que j'ai fais pour le moment c'est lancer le thread. (2 dernières lignes)
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(); }
SocketServeurMethods.java
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.
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; } }
Donc premier problème. Quand je me connecte j'ai ceci qui apparait
Ma socket est fermée ? Pourquoi ça ?
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)
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 :
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 SocketServeurMethods SSM1(2055, Textarea1); SocketServeurMethods SSM2(5022, Textarea2);
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.![]()
Partager