import java.net.*; import java.io.*; import java.util.*; public class JChatServer { private ServerSocket serverSocket; int clientPort; ArrayList clients; ArrayList nicks; public void start() throws IOException { clients = new ArrayList(); nicks = new ArrayList(); Socket client; serverSocket = new ServerSocket(7777); getServerInfo(); // Ciclo infinito in ascolto di eventuali Client while (true) { client = startListening(); clients.add(client); getClientInfo(client); startListeningSingleClient(client); } } private void startListeningSingleClient(Socket client) { Thread t = new Thread (new ParallelServer(client)); t.start(); } public class ParallelServer implements Runnable { Socket client; BufferedReader is; DataOutputStream os; public ParallelServer(Socket client) { this.client = client; try { // Stream di byte utilizzato per la comunicazione via socket is = new BufferedReader(new InputStreamReader(client.getInputStream())); os = new DataOutputStream(client.getOutputStream()); } catch (Exception ex) { } } public void run() { try { while (true) { sendMessage(receiveMessage(is), is, os, client); } } catch (Exception ex) { } } } public void getServerInfo() { // Informazioni sul Server in ascolto InetAddress indirizzo = serverSocket.getInetAddress(); String server = indirizzo.getHostAddress(); int port = serverSocket.getLocalPort(); System.out.println("In ascolto Server: " + server + " porta: " + port); } public void getClientInfo(Socket client) { // Informazioni sul Client che ha effettuato la chiamata InetAddress address = client.getInetAddress(); String clientInfo = address.getHostName(); clientPort = client.getPort(); System.out.println("In chiamata Client: " + clientInfo + " porta: " + clientPort); } public Socket startListening() throws IOException { System.out.println("In attesa di chiamate dai Client... "); return serverSocket.accept(); } public String receiveMessage(BufferedReader is) throws IOException { String strReceived = is.readLine(); if(strReceived.startsWith("~")) { // Controlla se il nick è gia' presente if (nicks.contains(strReceived.substring(1))) { strReceived = "NOGOODUSER"; } else nicks.add(strReceived.substring(1)); } else if(strReceived.startsWith("^")) { nicks.remove(strReceived.substring(1)); } System.out.println("Il Client ha inviato: " + strReceived); return strReceived ; } public void sendMessage(String recMsg, BufferedReader is, DataOutputStream os, Socket client ) throws IOException { int idxToRemove = -1; for(Iterator all = clients.iterator(); all.hasNext();) { Socket cl = (Socket)all.next(); if(recMsg.startsWith("~")) addNewUser(recMsg, cl, client); else if(recMsg.startsWith("^")) idxToRemove = removeUser(recMsg, idxToRemove, cl, client); else { if(recMsg.equals("NOGOODUSER") && cl.equals(client)) { new DataOutputStream(cl.getOutputStream()).writeBytes(recMsg + "\n"); idxToRemove = removeUser(recMsg, idxToRemove, cl, client); } else broadcastMessage(recMsg, cl); } } // Se ci sono client da rimuovere, tale rimozione viene effettuata // solo al termine del ciclo per evitare problemi sugli indici. if (idxToRemove > -1) clients.remove(idxToRemove); } private void addNewUser(String recMsg, Socket cl, Socket client) throws IOException { if (cl.equals(client)) { StringBuffer response = new StringBuffer(); for (int i = 0; i < nicks.size(); i++) { response.append(nicks.get(i)); response.append("~"); } String strResponse = "OKNEWUSER" + response.toString(); System.out.println(strResponse); new DataOutputStream(cl.getOutputStream()).writeBytes(strResponse + "\n"); } else { String strName = recMsg.substring(1); new DataOutputStream(cl.getOutputStream()).writeBytes("NEWUSER" + strName + "\n"); } } private int removeUser(String recMsg, int idxToRemove, Socket cl, Socket client) throws IOException { if (cl.equals(client)) { close(cl.getInputStream(), cl.getOutputStream(), cl); idxToRemove = clients.indexOf(cl); } else { String strName = recMsg.substring(1); new DataOutputStream(cl.getOutputStream()).writeBytes("REMOVEUSER" + strName + "\n"); } return idxToRemove; } private void broadcastMessage(String recMsg, Socket cl) throws IOException { // Il messaggio "NOGOODUSER" deve essere inviato // solo ad uno specifico client (gestito nella sendMessage). if(! recMsg.equals("NOGOODUSER")) new DataOutputStream(cl.getOutputStream()).writeBytes(recMsg + "\n"); } public void close(InputStream is, OutputStream os, Socket client) throws IOException { System.out.println("Chiamata close"); // chiusura della comunicazione con il Client os.close(); is.close(); System.out.println("Chiusura chiamata Client: " + client.getInetAddress().getHostName() + "su porta: " + clientPort); client.close(); } }