|
@@ -6,28 +6,31 @@ import java.util.ArrayList; // import the ArrayList class
|
6
|
6
|
|
7
|
7
|
|
8
|
8
|
public class User{
|
9
|
|
- final static int portUDPlistening_remoteUsr1 = 20001;
|
10
|
|
-
|
|
9
|
+
|
|
10
|
+ /*** CONSTANTES ***/
|
|
11
|
+ final static int portUDPlistening_remoteUsr2 = 20002;
|
|
12
|
+ final static int portUDPlistening_remoteUsr3 = 20003;
|
|
13
|
+
|
|
14
|
+ /*** VARIABLES ***/
|
11
|
15
|
protected InetAddress addIP;
|
12
|
16
|
protected String pseudo;
|
13
|
|
-
|
14
|
17
|
protected int portUDPsend;
|
15
|
18
|
protected int portUDPlistening;
|
16
|
19
|
protected int portTCP;
|
17
|
|
-
|
18
|
20
|
protected boolean actif;
|
19
|
21
|
|
20
|
|
- protected ArrayList<RemoteUser> remoteUserList = new ArrayList<RemoteUser>();
|
21
|
|
- protected ArrayList<RemoteUser> userChatList = new ArrayList<RemoteUser>();
|
|
22
|
+ protected ArrayList<RemoteUser> remoteUserList = new ArrayList<RemoteUser>(); // listes des utilisateurs actifs
|
|
23
|
+ protected ArrayList<RemoteUser> userChatList = new ArrayList<RemoteUser>(); // listes des utilisateurs avec qui un chat est actif
|
22
|
24
|
|
23
|
|
- protected UserListeningThread threadListeningUDP;
|
24
|
|
- public Boolean stopListeningUDPThread=false;
|
|
25
|
+ protected UserListeningThread threadListeningUDP; // UDP listening thread (pour répondre aux nouveaux utilisateurs)
|
25
|
26
|
|
26
|
27
|
/*
|
27
|
28
|
* Constructor of User
|
28
|
|
- * parameters
|
29
|
|
- * #nport
|
30
|
|
- * description : On récupère l'adresse de la machine, le numéro de port à utiliser(TODO), on demande un pseudo à l'utilisateur
|
|
29
|
+ * $parameters
|
|
30
|
+ * *
|
|
31
|
+ * *
|
|
32
|
+ * *
|
|
33
|
+ * $description : On récupère l'adresse de la machine, le numéro de port à utiliser(TODO), on demande un pseudo à l'utilisateur
|
31
|
34
|
* que l'on vérifie, une fois validé, l'utilisateur devient actif (Début de l'écoute UDP pour les pseudos)
|
32
|
35
|
*/
|
33
|
36
|
public User(int portUDPsend,int portUDPlistening,int portTCP) throws IOException{
|
|
@@ -44,28 +47,20 @@ public class User{
|
44
|
47
|
this.portUDPlistening = portUDPlistening;
|
45
|
48
|
this.portTCP = portTCP;
|
46
|
49
|
|
47
|
|
- this.setPseudo();
|
|
50
|
+ this.initPseudo();
|
48
|
51
|
|
49
|
52
|
this.setActif(true);
|
50
|
53
|
|
51
|
|
-
|
52
|
|
- //ask_change_pseudo();
|
53
|
|
- /*
|
54
|
|
- boolean wantstochange = true; //A faire avec un bouton dans SWING
|
55
|
|
- if(wantstochange) {
|
56
|
|
- //changePseudo();
|
57
|
|
- }
|
58
|
|
- */
|
59
|
|
- //this.waitProgramtoStop()
|
60
|
54
|
}
|
61
|
55
|
|
62
|
|
- /* remoteUser
|
63
|
|
- * Constructor of User simuled a remote user (Already log into our system)
|
64
|
|
- * parameters
|
65
|
|
- * #nport
|
66
|
|
- * #pseudo
|
67
|
|
- * description : On récupère l'adresse de la machine, le numéro de port à utiliser(TODO), on demande un pseudo à l'utilisateur
|
68
|
|
- * que l'on vérifie, une fois validé, l'utilisateur devient actif (Début de l'écoute UDP pour les pseudos)
|
|
56
|
+ /*
|
|
57
|
+ * Constructor of User (simulation des utilisateurs distants)
|
|
58
|
+ * $parameters
|
|
59
|
+ * *
|
|
60
|
+ * *
|
|
61
|
+ * *
|
|
62
|
+ * $description : On récupère l'adresse de la machine, le numéro de port à utiliser(TODO), on demande un pseudo à l'utilisateur
|
|
63
|
+ * que l'on vérifie, une fois validé, l'utilisateur devient actif (Début de l'écoute UDP pour les pseudos)
|
69
|
64
|
*/
|
70
|
65
|
public User(int portUDPsend,int portUDPlistening, int portTCP,String pseudo) {
|
71
|
66
|
try
|
|
@@ -84,53 +79,46 @@ public class User{
|
84
|
79
|
}
|
85
|
80
|
|
86
|
81
|
|
87
|
|
-
|
|
82
|
+ /*** GETTER ***/
|
88
|
83
|
public InetAddress getAddIP() {
|
89
|
84
|
return addIP;
|
90
|
85
|
}
|
91
|
|
-
|
92
|
|
-
|
93
|
|
- public void setAddIP(InetAddress addIP) {
|
94
|
|
- this.addIP = addIP;
|
95
|
|
- }
|
96
|
|
-
|
97
|
|
-
|
98
|
86
|
public String getPseudo() {
|
99
|
87
|
return pseudo;
|
100
|
88
|
}
|
101
|
|
-
|
|
89
|
+
|
102
|
90
|
public int getPortTCP() {
|
103
|
91
|
return portTCP;
|
104
|
92
|
}
|
105
|
|
-
|
106
|
|
-
|
107
|
|
- public void setPortTCP(int portTCP) {
|
108
|
|
- this.portTCP = portTCP;
|
109
|
|
- }
|
110
|
93
|
|
111
|
94
|
public int getPortUDPlistening() {
|
112
|
95
|
return portUDPlistening;
|
113
|
96
|
}
|
|
97
|
+
|
|
98
|
+ public int getPortUDPsend() {
|
|
99
|
+ return portUDPsend;
|
|
100
|
+ }
|
|
101
|
+ public boolean isActif() {
|
|
102
|
+ return actif;
|
|
103
|
+ }
|
|
104
|
+
|
|
105
|
+ /*** SETTER ***/
|
|
106
|
+ public void setAddIP(InetAddress addIP) {
|
|
107
|
+ this.addIP = addIP;
|
|
108
|
+ }
|
114
|
109
|
|
|
110
|
+ public void setPortTCP(int portTCP) {
|
|
111
|
+ this.portTCP = portTCP;
|
|
112
|
+ }
|
115
|
113
|
|
116
|
114
|
public void setPortUDPlistening(int portUDPlistening) {
|
117
|
115
|
this.portUDPlistening = portUDPlistening;
|
118
|
116
|
}
|
119
|
117
|
|
120
|
|
- public int getPortUDPsend() {
|
121
|
|
- return portUDPsend;
|
122
|
|
- }
|
123
|
|
-
|
124
|
|
-
|
125
|
118
|
public void setPortUDPsend(int portUDPsend) {
|
126
|
119
|
this.portUDPsend = portUDPsend;
|
127
|
120
|
}
|
128
|
121
|
|
129
|
|
- public boolean isActif() {
|
130
|
|
- return actif;
|
131
|
|
- }
|
132
|
|
-
|
133
|
|
-
|
134
|
122
|
public void setActif(boolean actif) {
|
135
|
123
|
notify_remote_user();
|
136
|
124
|
this.threadListeningUDP = new UserListeningThread("UDP Listening thread",this);
|
|
@@ -139,7 +127,13 @@ public class User{
|
139
|
127
|
this.actif=true;
|
140
|
128
|
}
|
141
|
129
|
|
|
130
|
+ /*** PROCEDURES ***/
|
|
131
|
+
|
|
132
|
+ /* notify_remote_user
|
|
133
|
+ * En utilisant le port UDP d'envoi, on envoi en broadcast les informations nous concernant
|
|
134
|
+ */
|
142
|
135
|
public void notify_remote_user() {
|
|
136
|
+ // Création du socket d'envoi d'information
|
143
|
137
|
DatagramSocket dgramSocket= null;
|
144
|
138
|
try {
|
145
|
139
|
dgramSocket= new DatagramSocket(portUDPsend,this.addIP);
|
|
@@ -147,24 +141,38 @@ public class User{
|
147
|
141
|
e.printStackTrace();
|
148
|
142
|
}
|
149
|
143
|
|
|
144
|
+ // Construction du message à envoyer
|
150
|
145
|
String toSend = this.addIP.toString()+":"+this.portTCP+":"+this.pseudo+":test";
|
151
|
|
- //System.out.println("Message avant envoi " +toSend);
|
152
|
|
- DatagramPacket outPacket= new DatagramPacket(toSend.getBytes(), toSend.length(),this.addIP, portUDPlistening_remoteUsr1);
|
153
|
|
-
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+ // Send information to usr2
|
|
149
|
+ DatagramPacket outPacket= new DatagramPacket(toSend.getBytes(), toSend.length(),this.addIP, portUDPlistening_remoteUsr2);
|
154
|
150
|
try {
|
155
|
151
|
dgramSocket.send(outPacket);
|
156
|
152
|
} catch (IOException e) {
|
157
|
153
|
e.printStackTrace();
|
158
|
154
|
}
|
|
155
|
+
|
|
156
|
+ // Send information to usr3
|
|
157
|
+ outPacket= new DatagramPacket(toSend.getBytes(), toSend.length(),this.addIP, portUDPlistening_remoteUsr3);
|
|
158
|
+ try {
|
|
159
|
+ dgramSocket.send(outPacket);
|
|
160
|
+ } catch (IOException e) {
|
|
161
|
+ e.printStackTrace();
|
|
162
|
+ }
|
|
163
|
+
|
159
|
164
|
dgramSocket.close();
|
160
|
165
|
}
|
161
|
166
|
|
162
|
|
- public void setPseudo() throws IOException {
|
|
167
|
+ /*initPseudo
|
|
168
|
+ * Demande à l'utilisateur de rentrer un pseudo et validation de ce dernier en demandant aux utilisateurs distants leurs informations
|
|
169
|
+ */
|
|
170
|
+ public void initPseudo() throws IOException {
|
163
|
171
|
Scanner sc1 = new Scanner(System.in); // Create a Scanner object
|
164
|
172
|
System.out.println("Enter nickname :");
|
165
|
173
|
String tmpPseudo = sc1.nextLine(); // Read user input
|
166
|
174
|
|
167
|
|
- while(!(this.validatePseudo(tmpPseudo))) {
|
|
175
|
+ while(!(this.validatePseudo(tmpPseudo))) { // On demande aux autres utilisateurs de nous envoyer leurs informations et on test si le pseudo est déjà utilisé
|
168
|
176
|
System.out.println("Enter another nickname :");
|
169
|
177
|
tmpPseudo = sc1.nextLine(); // Read user input
|
170
|
178
|
}
|
|
@@ -174,6 +182,15 @@ public class User{
|
174
|
182
|
System.out.println("Your nickname : " + tmpPseudo + " is valid !");
|
175
|
183
|
}
|
176
|
184
|
|
|
185
|
+ /* validatePseudo
|
|
186
|
+ * $parametres
|
|
187
|
+ * *tmpPseudo : String => Le pseudo à valider
|
|
188
|
+ * $description
|
|
189
|
+ * On envoi en broadcast (pour l'instant envoi sur les ports de notre ordinateur) d'une demande d'information
|
|
190
|
+ * On attends les réponses pendant 5 secondes
|
|
191
|
+ * On valide le pseudo en fonction des pseudos reçu
|
|
192
|
+ * On en profites pour ajouter les utilisateurs répondant à notre liste d'utilisateur distant (RemoteUser)
|
|
193
|
+ */
|
177
|
194
|
public Boolean validatePseudo(String tmpPseudo) throws IOException {
|
178
|
195
|
|
179
|
196
|
|
|
@@ -181,19 +198,24 @@ public class User{
|
181
|
198
|
InetAddress broadcastIP = InetAddress.getLocalHost(); // change to broadcast
|
182
|
199
|
//System.out.println(broadcastIP);
|
183
|
200
|
DatagramSocket dgramSocket = new DatagramSocket(this.portUDPsend,this.addIP);
|
184
|
|
-
|
185
|
201
|
byte[] buffer = new byte[256];
|
186
|
202
|
|
|
203
|
+ // Création du message à envoyer
|
187
|
204
|
String toSend = this.getAddIP()+":"+this.portUDPsend+":test";
|
188
|
|
- DatagramPacket outPacket= new DatagramPacket(toSend.getBytes(), toSend.length(),broadcastIP, portUDPlistening_remoteUsr1);
|
189
|
|
-
|
|
205
|
+
|
|
206
|
+ // Send to remote user 1
|
|
207
|
+ DatagramPacket outPacket= new DatagramPacket(toSend.getBytes(), toSend.length(),broadcastIP, portUDPlistening_remoteUsr2);
|
|
208
|
+ dgramSocket.send(outPacket);
|
|
209
|
+
|
|
210
|
+ // Send to remote user 2
|
|
211
|
+ outPacket= new DatagramPacket(toSend.getBytes(), toSend.length(),broadcastIP, portUDPlistening_remoteUsr3);
|
190
|
212
|
dgramSocket.send(outPacket);
|
191
|
213
|
|
|
214
|
+ // Initialisation des paramètres de la boucles
|
192
|
215
|
Boolean valid = true;
|
193
|
|
-
|
194
|
|
- Date oldDate = new Date();
|
195
|
|
- Date newDate = new Date();
|
196
|
216
|
|
|
217
|
+
|
|
218
|
+
|
197
|
219
|
DatagramPacket inPacket;
|
198
|
220
|
String response = null;
|
199
|
221
|
String[] lstresponse= new String [4];
|
|
@@ -203,6 +225,8 @@ public class User{
|
203
|
225
|
System.out.print("Wait for pseudo validation ...\n");
|
204
|
226
|
|
205
|
227
|
int nbReponse =0;
|
|
228
|
+ Date oldDate = new Date();
|
|
229
|
+ Date newDate = new Date();
|
206
|
230
|
while( (newDate.getTime()-oldDate.getTime()) < 5000 && valid) {
|
207
|
231
|
|
208
|
232
|
nbReponse++;
|
|
@@ -217,18 +241,19 @@ public class User{
|
217
|
241
|
buffer = inPacket.getData();
|
218
|
242
|
response = new String(buffer);
|
219
|
243
|
|
220
|
|
- if(arecu) {
|
221
|
|
- //System.out.println("Reponse : "+response);
|
222
|
|
-
|
|
244
|
+ if(arecu) {
|
|
245
|
+ // On découpe la réponse en tableau de string ([adresseIP,tcpPort,nickname])
|
223
|
246
|
lstresponse = response.split(":");
|
224
|
247
|
|
|
248
|
+ // Affichage de la réponse
|
225
|
249
|
System.out.println("Remote user n°"+nbReponse);
|
226
|
250
|
System.out.println("\tIP : "+lstresponse[0]);
|
227
|
251
|
System.out.println("\tn°Port : "+lstresponse[1]);
|
228
|
252
|
System.out.println("\tpseudo : "+lstresponse[2]);
|
229
|
253
|
|
|
254
|
+ // Si reception on ajoute l'utilisateur à notre liste d'utilisateur distant
|
230
|
255
|
this.addRemoteUser(InetAddress.getByName(lstresponse[0].split("/")[1]),Integer.parseInt(lstresponse[1]),lstresponse[2]);
|
231
|
|
- valid= (tmpPseudo.compareTo(lstresponse[2])!=0);
|
|
256
|
+ valid= (tmpPseudo.compareTo(lstresponse[2])!=0); // On regarde la différence entre notre pseudo et le pseudo reçu
|
232
|
257
|
|
233
|
258
|
}
|
234
|
259
|
|
|
@@ -257,7 +282,7 @@ public class User{
|
257
|
282
|
}
|
258
|
283
|
// change pseudo
|
259
|
284
|
|
260
|
|
-private void changePseudo() throws IOException { //seule différence avec setPseudo c'est qu'on check si on remet pas le même
|
|
285
|
+private void setPseudo() throws IOException { //seule différence avec setPseudo c'est qu'on check si on remet pas le même
|
261
|
286
|
String oldPseudo = this.pseudo; //Saves the old one for comparison
|
262
|
287
|
|
263
|
288
|
Scanner sc3 = new Scanner(System.in); // Create a Scanner object
|
|
@@ -275,23 +300,25 @@ private void changePseudo() throws IOException { //seule diff
|
275
|
300
|
|
276
|
301
|
notify_remote_user();
|
277
|
302
|
}
|
278
|
|
-
|
|
303
|
+ /*printRemoteUserList
|
|
304
|
+ * $descrition
|
|
305
|
+ * Affichage de la liste d'utilisateur actif avec leurs index dans la liste
|
|
306
|
+ */
|
279
|
307
|
public void printRemoteUserList() {
|
280
|
|
- System.out.println("Internal list of remote users:\n");
|
|
308
|
+ System.out.println("Internal list of active remote users:\n");
|
281
|
309
|
|
282
|
310
|
for(int i=0; i<this.remoteUserList.size(); i++) {
|
283
|
|
- String pseudo = this.remoteUserList.get(i).getPseudo();
|
284
|
|
- int Port = this.remoteUserList.get(i).getRemoteUserPort();
|
285
|
|
-
|
286
|
|
- System.out.println("("+i+")"
|
287
|
|
- +"Username: " + pseudo + "\n"
|
288
|
|
- + "IP Adress: " + this.remoteUserList.get(i).getRemoteUserIP() + "\n"
|
289
|
|
- + "Port: " + Port + "\n" + "\n");
|
|
311
|
+ System.out.println("- ("+i+") Username: " + this.remoteUserList.get(i).getPseudo());
|
290
|
312
|
}
|
291
|
313
|
}
|
292
|
314
|
|
|
315
|
+ /*getOneActiveUser
|
|
316
|
+ * $description
|
|
317
|
+ * Laisse l'utilisateur choisir parmis la liste d'utilisateur actif celui avec lequel il souhaite échangé via un chat
|
|
318
|
+ */
|
293
|
319
|
public void getOneActiveUser() throws UnknownHostException {
|
294
|
|
- Scanner sc2= new Scanner(System.in);
|
|
320
|
+ this.printRemoteUserList();
|
|
321
|
+ Scanner sc2= new Scanner(System.in);
|
295
|
322
|
System.out.println("Please, enter one active user that you saw on the list to start a conversation with");
|
296
|
323
|
int index=Integer.parseInt(sc2.nextLine());
|
297
|
324
|
|
|
@@ -309,25 +336,26 @@ private void changePseudo() throws IOException { //seule diff
|
309
|
336
|
}
|
310
|
337
|
|
311
|
338
|
public static void main(String[] args) throws IOException, InterruptedException {
|
312
|
|
- User usr1 = new User(12221,portUDPlistening_remoteUsr1,22221,"Mike");
|
313
|
339
|
|
314
|
|
- User usr2 = new User(12222,20002,22222);
|
|
340
|
+ // Création des utilisateurs
|
|
341
|
+ User usr2 = new User(12222,portUDPlistening_remoteUsr2,22222,"Mike"); // simulation d'un utilisateur distant n1
|
|
342
|
+ User usr3 = new User(12223,portUDPlistening_remoteUsr3,22223,"Alice"); // simulation d'un utilisateur distant n2
|
|
343
|
+ User usr1 = new User(12221,20001,22221); // Notre utilisateur locale
|
315
|
344
|
|
|
345
|
+ // Fonction appelé par notre utilisateur locale
|
|
346
|
+ usr1.printRemoteUserList();
|
|
347
|
+ usr1.getOneActiveUser();
|
|
348
|
+ usr1.setPseudo();
|
316
|
349
|
|
317
|
|
- //User usr3 = new User(12229);
|
318
|
|
-
|
319
|
|
- // Attend une réponse pour fermer l'écoute UDP
|
320
|
|
- usr2.printRemoteUserList();
|
321
|
|
- usr2.getOneActiveUser();
|
322
|
|
-
|
323
|
|
- usr2.changePseudo();
|
324
|
|
-
|
|
350
|
+ // On attends 5 secondes
|
325
|
351
|
System.out.println("Sleep mode for 5 seconds");
|
326
|
352
|
Thread.sleep(5000);
|
327
|
|
-
|
|
353
|
+ // On ferme les différents threads et socket d'écoute
|
328
|
354
|
usr1.threadListeningUDP.close();
|
329
|
355
|
usr2.threadListeningUDP.close();
|
330
|
|
- System.out.println("Fin du programme");
|
|
356
|
+ usr3.threadListeningUDP.close();
|
|
357
|
+
|
|
358
|
+ System.out.println("End");
|
331
|
359
|
|
332
|
360
|
|
333
|
361
|
}
|