No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

NetworkClient.java 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. package chat;
  2. import java.net.*;
  3. import javax.swing.*;
  4. import java.awt.*;
  5. import java.util.List;
  6. import java.awt.event.*;
  7. import java.io.*;
  8. import java.util.*;
  9. import chat.User;
  10. import chat.Message;
  11. public class NetworkClient {
  12. private User user;
  13. private List<User> known_users;
  14. private List<User> known_outdoor_users;
  15. private List<Socket> dest_sockets;
  16. private List<Socket> outdoor_dest_sockets;
  17. private JTextArea chatText;
  18. private JTextArea knownUsersPanel;
  19. static String getLocalIP() {
  20. String ip = "";
  21. try(final DatagramSocket socket = new DatagramSocket()){
  22. socket.connect(InetAddress.getByName("8.8.8.8"), 10002);
  23. ip = socket.getLocalAddress().getHostAddress();
  24. }
  25. catch(Exception e)
  26. {
  27. System.out.println("niiiiiiiikkk");
  28. }
  29. return ip;
  30. }
  31. NetworkClient(JTextArea in_chatText, JTextArea in_knownUsersPanel)
  32. {
  33. user = new User("");
  34. chatText = in_chatText;
  35. knownUsersPanel = in_knownUsersPanel;
  36. known_users = new ArrayList<User>();
  37. known_outdoor_users = new ArrayList<User>();
  38. dest_sockets = new ArrayList<Socket>();
  39. outdoor_dest_sockets = new ArrayList<Socket>();
  40. }
  41. boolean connect(String username, Boolean outdoor, String destinationIP)
  42. {
  43. boolean nameAvailable = true;
  44. boolean connected = false;
  45. DatagramSocket connectionSocket;
  46. DatagramSocket userListSocket;
  47. DatagramPacket connectionRequest;
  48. DatagramPacket responsePacket;
  49. String[] usernameList;
  50. String[] outdoorUsernameList;
  51. String[] addressList;
  52. int portNumber = 1237;
  53. byte[] buffer1 = new byte[20000];
  54. if(username == null || username.compareTo("") == 0)
  55. return false;
  56. try
  57. {
  58. try
  59. {
  60. if(!outdoor)
  61. {
  62. connectionSocket = new DatagramSocket();
  63. userListSocket = new DatagramSocket(1337);
  64. userListSocket.setSoTimeout(500);
  65. connectionRequest = new DatagramPacket(username.getBytes(), username.length(),
  66. InetAddress.getByName(destinationIP), 1234);
  67. /*l'adresse de broadcast est hardcodée ici
  68. pour tester avec Hamachi, il faut la remplacer par celle du réseau local virtuel*/
  69. System.out.println("Sending connection request");
  70. connectionSocket.send(connectionRequest);
  71. responsePacket = new DatagramPacket(buffer1, buffer1.length);
  72. System.out.println("Waiting for reply");
  73. userListSocket.receive(responsePacket);
  74. System.out.println("Received a reply from " + responsePacket.getAddress().getHostAddress());
  75. String[] response = new String(responsePacket.getData()).trim().split(";");
  76. usernameList = response[0].split(" ");
  77. outdoorUsernameList = response[1].split(" ");
  78. addressList = response[2].split(" ");
  79. portNumber = Integer.parseInt(response[3]);
  80. connectionSocket.close();
  81. userListSocket.close();
  82. }
  83. else
  84. {
  85. Socket requestSocket = new Socket(destinationIP, 1233);
  86. BufferedReader in = new BufferedReader(new InputStreamReader(requestSocket.getInputStream()));
  87. PrintWriter out = new PrintWriter(requestSocket.getOutputStream(), true);
  88. out.println(username);
  89. String[] response = in.readLine().split(";");
  90. usernameList = response[0].split(" ");
  91. outdoorUsernameList = response[1].split(" ");
  92. addressList = new String[0];
  93. portNumber = Integer.parseInt(response[2]);
  94. }
  95. for(String u:usernameList)
  96. {
  97. nameAvailable = nameAvailable && (!username.equals(u));
  98. }
  99. if(nameAvailable)
  100. {
  101. System.out.println(usernameList.length + " users currently connected");
  102. for(String u:usernameList)
  103. {
  104. known_users.add(new User (u));
  105. }
  106. for(String u:outdoorUsernameList)
  107. {
  108. known_outdoor_users.add(new User (u));
  109. }
  110. for(String a:addressList)
  111. {
  112. Socket s = new Socket(a, portNumber);
  113. dest_sockets.add(s);
  114. (new ReceiveThread(user, s, chatText, known_users, known_outdoor_users, knownUsersPanel, dest_sockets, outdoor_dest_sockets, false)).start();
  115. }
  116. Collections.sort(known_users);
  117. connected = true;
  118. }
  119. }
  120. catch(SocketTimeoutException e)
  121. //Si on est tout seul sur le réseau (on ne reçoit aucune réponse)
  122. {
  123. System.out.println("Reply timed out");
  124. connected = true;
  125. }
  126. }
  127. catch (SocketException e2)
  128. {
  129. e2.printStackTrace();
  130. }
  131. catch (Exception e3)
  132. {
  133. e3.printStackTrace();
  134. }
  135. if(connected)
  136. {
  137. if(!outdoor)
  138. {
  139. (new ConnectionListenerThread(user, known_users, known_outdoor_users, dest_sockets, outdoor_dest_sockets, chatText, knownUsersPanel, portNumber)).start();
  140. (new OutdoorListenerThread(user, known_users, known_outdoor_users, dest_sockets, outdoor_dest_sockets, chatText, knownUsersPanel)).start();
  141. try
  142. {
  143. ServerSocket s1 = new ServerSocket(portNumber);
  144. (new ListenerStartThread(s1, dest_sockets)).start();
  145. Socket s2 = new Socket(getLocalIP(), portNumber);
  146. System.out.println(getLocalIP());
  147. /*Attention, getLocalIP ne marche que sur un même réseau physique
  148. * pour tester avec Hamachi, il faut hardcoder les IP
  149. */
  150. (new ReceiveThread(user, s2, chatText, known_users, known_outdoor_users, knownUsersPanel, dest_sockets, outdoor_dest_sockets, false)).start();
  151. }
  152. catch(IOException e)
  153. {
  154. e.printStackTrace();
  155. }
  156. }
  157. else
  158. {
  159. try
  160. {
  161. Socket s = new Socket(destinationIP, portNumber);
  162. dest_sockets.add(s);
  163. (new ReceiveThread(user, s, chatText, known_users, known_outdoor_users, knownUsersPanel, dest_sockets, outdoor_dest_sockets, false)).start();
  164. }
  165. catch(IOException e)
  166. {
  167. e.printStackTrace();
  168. }
  169. }
  170. user.setName(username);
  171. send(new ConnectNotification(user, false, outdoor));
  172. }
  173. return connected;
  174. }
  175. void send (Notification notif)
  176. {
  177. for(Socket s:dest_sockets)
  178. {
  179. try
  180. {
  181. //System.out.println(s.getInetAddress().getHostAddress() + ": local port " + s.getLocalPort() + ", remote port " + s.getPort());
  182. ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
  183. out.writeObject(notif);
  184. }
  185. catch(IOException e){}
  186. }
  187. for(Socket s:outdoor_dest_sockets)
  188. {
  189. try
  190. {
  191. //System.out.println(s.getInetAddress().getHostAddress() + ": local port " + s.getLocalPort() + ", remote port " + s.getPort());
  192. ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
  193. out.writeObject(notif);
  194. }
  195. catch(IOException e){}
  196. }
  197. }
  198. void disconnect()
  199. {
  200. send(new DisconnectNotification(user, false));
  201. try
  202. {
  203. Thread.sleep(1000);
  204. }
  205. catch(InterruptedException e) {}
  206. for(Socket s:dest_sockets)
  207. {
  208. try
  209. {
  210. s.close();
  211. }
  212. catch(IOException e){}
  213. }
  214. }
  215. User getUser()
  216. {
  217. return user;
  218. }
  219. }