123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627 |
- package chat;
-
- import java.net.*;
-
- import javax.swing.*;
-
- import java.awt.*;
- import java.util.List;
- import java.awt.event.*;
-
- import java.io.*;
- import java.util.*;
-
- import chat.User;
- import chat.Message;
-
- class OutdoorListenerThread extends Thread {
- User user;
- JTextArea displayArea;
- JTextArea knownUsersPanel;
- List<User> known_users;
- List<User> known_outdoor_users;
- List<Socket> dest_sockets;
- List<Socket> outdoor_dest_sockets;
- int portNumber;
-
- OutdoorListenerThread(User in_user, List<User> in_known_users, List<User> in_known_outdoor_users, List<Socket> in_dest_sockets, List<Socket> in_outdoor_dest_sockets,
- JTextArea in_displayArea, JTextArea in_knownUsersPanel)
- {
- user = in_user;
- known_users = in_known_users;
- known_outdoor_users = in_known_outdoor_users;
- dest_sockets = in_dest_sockets;
- outdoor_dest_sockets = in_outdoor_dest_sockets;
- displayArea = in_displayArea;
- knownUsersPanel = in_knownUsersPanel;
- portNumber = 2344;
- }
- public void run()
- {
- boolean exit = false;
- boolean accepted = true;
-
- String notification;
- String username;
- String response = "";
-
- byte[] buffer = new byte[100];
- DatagramPacket notifPacket = new DatagramPacket(buffer, buffer.length);
- DatagramSocket notifSocket;
- byte[] notifBytes;
-
- try
- {
- while(!exit)
- {
- try
- {
- ServerSocket servSocket = new ServerSocket(1233);
- System.out.println("Waiting for connection request");
- Socket link = servSocket.accept();
- BufferedReader in = new BufferedReader(new InputStreamReader(link.getInputStream()));
- PrintWriter out = new PrintWriter(link.getOutputStream(), true);
- username = in.readLine();
- System.out.println("Received a request from " + username + "@" + link.getRemoteSocketAddress().toString());
-
- response = "";
- for(User u:known_users)
- {
- response += u.getName() + " ";
- }
- response = response.trim();
- response += ";";
- for(User u:known_outdoor_users)
- {
- response += u.getName() + " ";
- }
- response = response.trim();
- for(Socket s:dest_sockets)
- {
- response += s.getInetAddress().getHostAddress() + " ";
- }
- response = response.trim();
- response += ";" + (portNumber+1);
-
- out.println(response);
-
- accepted = true;
- for(User a:known_users)
- {
- accepted = accepted && (!username.equals(a.getName()));
- }
- for(User a:known_outdoor_users)
- {
- accepted = accepted && (!username.equals(a.getName()));
- }
- if(accepted)
- {
- notification = "+" + username;
- notifBytes = notification.getBytes();
- notifSocket = new DatagramSocket();
- notifPacket = new DatagramPacket(notifBytes, notifBytes.length, InetAddress.getByName("192.168.1.255"), 1234);
- notifSocket.send(notifPacket);
-
- portNumber++;
- Socket s = (new ServerSocket(portNumber)).accept();
- (new ReceiveThread(user, s, displayArea, known_users, known_outdoor_users, knownUsersPanel, dest_sockets, outdoor_dest_sockets, true)).start();
- outdoor_dest_sockets.add(s);
- }
- servSocket.close();
- }
- catch(SocketTimeoutException e) {}
- }
- }
- catch(Exception e)
- {
- e.printStackTrace();
- System.out.println(e.getMessage());
- }
- }
- }
-
- class ReceiveThread extends Thread {
- User user;
- Socket socket;
- JTextArea displayArea;
- JTextArea knownUsersPanel;
- Boolean isOutdoor;
- List<User> known_users;
- List<User> known_outdoor_users;
- List<Socket> dest_sockets;
- List<Socket> outdoor_dest_sockets;
-
- ReceiveThread(User in_user, Socket in_socket, JTextArea in_displayArea, List<User> in_known_users, List<User> in_known_outdoor_users,
- JTextArea in_knownUsersPanel, List<Socket> in_dest_sockets, List<Socket> in_outdoor_dest_sockets, Boolean in_isOutdoor)
- {
- user = in_user;
- socket = in_socket;
- displayArea = in_displayArea;
- knownUsersPanel = in_knownUsersPanel;
- known_users = in_known_users;
- known_outdoor_users = in_known_outdoor_users;
- dest_sockets = in_dest_sockets;
- outdoor_dest_sockets = in_outdoor_dest_sockets;
- isOutdoor = in_isOutdoor;
- }
- public void run()
- {
- boolean exit = false;
- try
- {
- while(!exit)
- {
- ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
- Message message = (Message) in.readObject();
- if(isOutdoor)
- {
- for(Socket s:dest_sockets)
- {
- try
- {
- ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
- out.writeObject(new Message(message.getAuthor(), message.getText(), true));
- }
- catch(IOException e){}
- }
- }
- else
- {
- if(message.getText() != null)
- {
- displayArea.append(message.getAuthor() + " : " + message.getText() + "\n");
- }
- else
- {
- displayArea.append(message.getAuthor() + " has left the chat.\n");
- for(int i = 0;i < known_users.size();i ++)
- {
- if (known_users.get(i).getName().equals(message.getAuthor()))
- {
- known_users.remove(i);
- break;
- //System.out.println("Removing " + message.getAuthor());
- }
- }
- for(int i = 0;i < known_outdoor_users.size();i ++)
- {
- if (known_outdoor_users.get(i).getName().equals(message.getAuthor()))
- {
- known_outdoor_users.remove(i);
- break;
- //System.out.println("Removing " + message.getAuthor());
- }
- }
-
- if(!message.isRedirected() && message.getAuthor() != user.getName())
- {
- socket.close();
- if(!isOutdoor)
- dest_sockets.remove(socket);
- else
- outdoor_dest_sockets.remove(socket);
- }
-
- knownUsersPanel.setText("");
- knownUsersPanel.append("Indoor users:\n");
- for(User a:known_users)
- {
- knownUsersPanel.append(" " + a.getName() + " \n");
- }
- knownUsersPanel.append("\nOutdoor users:\n");
- for(User a:known_outdoor_users)
- {
- knownUsersPanel.append(" " + a.getName() + " \n");
- }
- }
- displayArea.setCaretPosition(displayArea.getDocument().getLength());
- }
- if(message.getAuthor() != user.getName())
- {
- for(Socket s:outdoor_dest_sockets)
- {
- try
- {
- ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
- out.writeObject(new Message(message.getAuthor(), message.getText(), true));
- }
- catch(IOException e){}
- }
- }
- }
- }
- catch(EOFException e) {}
- catch(Exception e)
- {
- e.printStackTrace();
- }
- }
- }
-
- class ConnectionListenerThread extends Thread {
- User user;
- JTextArea displayArea;
- JTextArea knownUsersPanel;
- List<User> known_users;
- List<User> known_outdoor_users;
- List<Socket> dest_sockets;
- List<Socket> outdoor_dest_sockets;
- int portNumber;
-
- ConnectionListenerThread(User in_user, List<User> in_known_users, List<User> in_known_outdoor_users, List<Socket> in_dest_sockets, List<Socket> in_outdoor_dest_sockets,
- JTextArea in_displayArea, JTextArea in_knownUsersPanel, int in_portNumber)
- {
- user = in_user;
- known_users = in_known_users;
- dest_sockets = in_dest_sockets;
- outdoor_dest_sockets = in_outdoor_dest_sockets;
- displayArea = in_displayArea;
- knownUsersPanel = in_knownUsersPanel;
- portNumber = in_portNumber;
- }
- public void run()
- {
- boolean exit = false;
- boolean accepted = true;
- boolean outdoor;
- byte[] buffer = new byte[100];
- DatagramPacket request = new DatagramPacket(buffer, buffer.length);
- DatagramPacket responsePacket;
-
- DatagramSocket requestSocket;
- DatagramSocket responseSocket;
-
- String username;
- String response = "";
-
- byte[] responseBytes;
- try
- {
- requestSocket = new DatagramSocket(1234);
- responseSocket = new DatagramSocket();
-
- while(!exit)
- {
- try
- {
- System.out.println("Waiting for connection request");
- requestSocket.receive(request);
- username = new String(request.getData(), 0, request.getLength());
-
- if(username.charAt(0) == '+')
- {
- username = username.substring(1);
- outdoor = true;
- }
- else
- {
- outdoor = false;
- InetAddress clientAddress= request.getAddress();
- System.out.println("Received a request from " + username + "@" + clientAddress.getHostAddress());
-
- response = "";
- for(User u:known_users)
- {
- response += u.getName() + " ";
- }
- response = response.trim();
- response += ";";
- for(Socket s:dest_sockets)
- {
- response += s.getInetAddress().getHostAddress() + " ";
- }
- response = response.trim();
- response += ";" + (portNumber+1);
-
- System.out.println("Response :" + response);
- responseBytes = response.getBytes();
- responsePacket = new DatagramPacket(responseBytes, responseBytes.length, clientAddress, 1337);
- responseSocket.send(responsePacket);
- }
- accepted = true;
- for(User a:known_users)
- {
- accepted = accepted && (!username.equals(a.getName()));
- }
- for(User a:known_outdoor_users)
- {
- accepted = accepted && (!username.equals(a.getName()));
- }
- if(accepted)
- {
- if(outdoor)
- {
- known_outdoor_users.add(new User(username));
- Collections.sort(known_outdoor_users);
- }
- else
- {
- portNumber++;
- Socket s = (new ServerSocket(portNumber)).accept();
- (new ReceiveThread(user, s, displayArea, known_users, known_outdoor_users, knownUsersPanel, dest_sockets, outdoor_dest_sockets, false)).start();
- dest_sockets.add(s);
-
- known_users.add(new User(username));
-
- Collections.sort(known_users);
- }
-
- displayArea.append(username + " has joined the chat.\n");
- displayArea.setCaretPosition(displayArea.getDocument().getLength());
-
- knownUsersPanel.setText("");
- knownUsersPanel.append("Indoor users:\n");
- for(User a:known_users)
- {
- knownUsersPanel.append(" " + a.getName() + " \n");
- }
- knownUsersPanel.append("\nOutdoor users:\n");
- for(User a:known_outdoor_users)
- {
- knownUsersPanel.append(" " + a.getName() + " \n");
- }
- }
- }
- catch(SocketTimeoutException e) {}
- }
- }
- catch(Exception e)
- {
- e.printStackTrace();
- System.out.println(e.getMessage());
- }
- }
- }
-
- class ListenerStartThread extends Thread {
-
- ServerSocket s;
- List<Socket> dest_sockets;
- ListenerStartThread(ServerSocket in_s, List<Socket> in_dest_sockets)
- {
- s = in_s;
- dest_sockets = in_dest_sockets;
- }
- public void run()
- {
- try
- {
- dest_sockets.add(s.accept());
- }
- catch(IOException e) {}
- }
- }
-
- public class NetworkClient {
- private User user;
- private List<User> known_users;
- private List<User> known_outdoor_users;
- private List<Socket> dest_sockets;
- private List<Socket> outdoor_dest_sockets;
- private JTextArea chatText;
- private JTextArea knownUsersPanel;
-
- static String getLocalIP() {
- String ip = "";
- try(final DatagramSocket socket = new DatagramSocket()){
- socket.connect(InetAddress.getByName("8.8.8.8"), 10002);
- ip = socket.getLocalAddress().getHostAddress();
- }
- catch(Exception e)
- {
- System.out.println("niiiiiiiikkk");
- }
- return ip;
- }
-
- NetworkClient(JTextArea in_chatText, JTextArea in_knownUsersPanel)
- {
- user = new User("");
- chatText = in_chatText;
- knownUsersPanel = in_knownUsersPanel;
- known_users = new ArrayList<User>();
- known_outdoor_users = new ArrayList<User>();
- dest_sockets = new ArrayList<Socket>();
- outdoor_dest_sockets = new ArrayList<Socket>();
- }
-
- boolean connect(String username, Boolean outdoor, String destinationIP)
- {
- boolean nameAvailable = true;
- boolean connected = false;
- DatagramSocket connectionSocket;
- DatagramSocket userListSocket;
-
- DatagramPacket connectionRequest;
- DatagramPacket responsePacket;
-
- String[] usernameList;
- String[] addressList;
-
- int portNumber = 1237;
- byte[] buffer1 = new byte[20000];
-
- if(username == null || username.compareTo("") == 0)
- return false;
-
- try
- {
- try
- {
- if(!outdoor)
- {
- connectionSocket = new DatagramSocket();
- userListSocket = new DatagramSocket(1337);
-
- userListSocket.setSoTimeout(500);
-
- connectionRequest = new DatagramPacket(username.getBytes(), username.length(),
- InetAddress.getByName(destinationIP), 1234);
- /*l'adresse de broadcast est hardcodée ici
- pour tester avec Hamachi, il faut la remplacer par celle du réseau local virtuel*/
- System.out.println("Sending connection request");
- connectionSocket.send(connectionRequest);
-
- responsePacket = new DatagramPacket(buffer1, buffer1.length);
-
- System.out.println("Waiting for reply");
- userListSocket.receive(responsePacket);
- System.out.println("Received a reply from " + responsePacket.getAddress().getHostAddress());
-
- String[] response = new String(responsePacket.getData()).trim().split(";");
-
- usernameList = response[0].split(" ");
- addressList = response[1].split(" ");
- portNumber = Integer.parseInt(response[2]);
-
- connectionSocket.close();
- userListSocket.close();
- }
- else
- {
- Socket requestSocket = new Socket(destinationIP, 1233);
- BufferedReader in = new BufferedReader(new InputStreamReader(requestSocket.getInputStream()));
- PrintWriter out = new PrintWriter(requestSocket.getOutputStream(), true);
- out.println(username);
- String[] response = in.readLine().split(";");
- usernameList = response[0].split(" ");
- addressList = new String[0];
- portNumber = Integer.parseInt(response[2]);
- }
-
- for(String u:usernameList)
- {
- nameAvailable = nameAvailable && (!username.equals(u));
- }
- if(nameAvailable)
- {
- System.out.println(usernameList.length + " users currently connected");
- for(String u:usernameList)
- {
- known_users.add(new User (u));
- }
- for(String a:addressList)
- {
- Socket s = new Socket(a, portNumber);
- dest_sockets.add(s);
- (new ReceiveThread(user, s, chatText, known_users, known_outdoor_users, knownUsersPanel, dest_sockets, outdoor_dest_sockets, false)).start();
- }
- Collections.sort(known_users);
- connected = true;
- }
- }
- catch(SocketTimeoutException e)
- //Si on est tout seul sur le réseau (on ne reçoit aucune réponse)
- {
- System.out.println("Reply timed out");
- connected = true;
- }
- }
- catch (SocketException e2)
- {
- e2.printStackTrace();
- }
- catch (Exception e3)
- {
- e3.printStackTrace();
- }
-
- if(connected)
- {
- if(!outdoor)
- {
- (new ConnectionListenerThread(user, known_users, known_outdoor_users, dest_sockets, outdoor_dest_sockets, chatText, knownUsersPanel, portNumber)).start();
- (new OutdoorListenerThread(user, known_users, known_outdoor_users, dest_sockets, outdoor_dest_sockets, chatText, knownUsersPanel)).start();
-
- try
- {
- ServerSocket s1 = new ServerSocket(portNumber);
- (new ListenerStartThread(s1, dest_sockets)).start();
-
- Socket s2 = new Socket(getLocalIP(), portNumber);
- System.out.println(getLocalIP());
- /*Attention, getLocalIP ne marche que sur un même réseau physique
- * pour tester avec Hamachi, il faut hardcoder les IP
- */
- (new ReceiveThread(user, s2, chatText, known_users, known_outdoor_users, knownUsersPanel, dest_sockets, outdoor_dest_sockets, false)).start();
- }
- catch(IOException e)
- {
- e.printStackTrace();
- }
- }
- else
- {
- try
- {
- Socket s = new Socket(destinationIP, portNumber);
- dest_sockets.add(s);
- (new ReceiveThread(user, s, chatText, known_users, known_outdoor_users, knownUsersPanel, dest_sockets, outdoor_dest_sockets, false)).start();
- }
- catch(IOException e)
- {
- e.printStackTrace();
- }
- }
-
- user.setName(username);
- known_users.add(new User(username));
- Collections.sort(known_users);
-
- chatText.append(username + " has joined the chat.\n");
- chatText.setCaretPosition(chatText.getDocument().getLength());
-
- knownUsersPanel.setText("");
- knownUsersPanel.append(" Online :\n");
- for(User a:known_users)
- {
- knownUsersPanel.append(" " + a.getName() + " \n");
- }
- }
-
- return connected;
- }
-
- void send (String message)
- {
- for(Socket s:dest_sockets)
- {
- try
- {
- //System.out.println(s.getInetAddress().getHostAddress() + ": local port " + s.getLocalPort() + ", remote port " + s.getPort());
- ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
- out.writeObject(new Message(user.getName(), message, false));
- }
- catch(IOException e){}
- }
- for(Socket s:outdoor_dest_sockets)
- {
- try
- {
- //System.out.println(s.getInetAddress().getHostAddress() + ": local port " + s.getLocalPort() + ", remote port " + s.getPort());
- ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
- out.writeObject(new Message(user.getName(), message, false));
- }
- catch(IOException e){}
- }
- }
-
- void disconnect()
- {
- send(null);
- try
- {
- Thread.sleep(1000);
- }
- catch(InterruptedException e) {}
-
- for(Socket s:dest_sockets)
- {
- try
- {
- s.close();
- }
- catch(IOException e){}
- }
- }
- }
|