import java.net.*;
import java.io.*;
import java.util.*;
//Progetto Ingegneria del Software
//Autore: Ignazio Coco
//Matricola: 616/000075
/**
* Thread per la gestione di una connessione al server dei nomi
*/
class ServerThread extends Thread {
/**
* Riferimento alla Socket gestita dal thread
*/
private Socket socket;
/**
* riferimento alla lista che mantiene i nomi e gli ip associati degli
* utenti connessi
*/
private LinkedList lista;
/**
* Questo parametro permette di impostare il programma in modalità
* di debug. Ciò comporta la visualizzazione di tutti i messaggi
* durante la fase di esecuzione
*/
public boolean debug=true;
/**
* Costruttore del thread
* @param socket Riferimento alla socket da gestire
* @param lista Riferimento alla lista in cui inserire il nuovo utente
*/
public ServerThread (Socket socket, LinkedList lista) {
this.socket = socket;
this.lista = lista;
}
/**
* Metodo che gestisce l"esecuzione del thread
*/
public void run() {
try {
DataInputStream is = new DataInputStream(socket.getInputStream());
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
String stringa = is.readLine();
String tmp[] = stringa.split(":");
String comando = tmp[0];
String parametro = tmp[1];
if (comando.equals("retrieveIp")) {
if (debug) System.out.println("Richiesta IP");
retrieveIp(os, parametro);
if (debug) System.out.println("Dati inviati");
}
if (comando.equals("connect")) {
if (debug) System.out.println("Richiesta connessione");
connect(socket, os, parametro);
if (debug) System.out.println("Dati acquisiti");
}
if (comando.equals("disconnect")) {
if (debug) System.out.println("Richiesta disconnessione");
disconnect(parametro);
if (debug) System.out.println("Scollegato");
}
if (comando.equals("retrieveName")) {
if (debug) System.out.println("Richiesta Nome");
retrieveName(os, parametro);
if (debug) System.out.println("Dati inviati");
}
os.close();
is.close();
socket.close();
if (debug) System.out.println("Socket Chiuso");
}
catch (IOException e) {
System.out.println("IOException: " + e);
if (debug) System.out.println("Errore su metodo run classe serverthread");
}
}
/**
* Metodo che connette l"utente alla chat. Si occupa di registrare l"
* utente usando il suo nickname ed associandolo al suo indirizzo Ip
* @param os Lo stream su cui scrivere la risposta (l"esito della
* connessione)
* @param sk Riferimento alla socket dell"utente
* @param nome Il nome dell"utente che sta cercando di collegarsi
* @return Un intero che indica l"esito dell"operazione
*/
public int connect(Socket sk, DataOutputStream os, String nome) {
InetAddress address = sk.getInetAddress();
String indIp = address.getHostAddress();
int porta = 7777;
String mess=nome+":"+indIp+":"+porta;
if (debug) System.out.println("Connesso:" + mess);
String stringa="", tmp[]=null, nomeS="";
for (int i=0;i<lista.size();i++) {
stringa=(String)lista.get(i);
tmp = stringa.split(":");
nomeS=tmp[0];
if (nomeS.equals(nome)) {
if (debug) System.out.println("Nome già registrato");
try {
os.writeBytes("###Nome già registrato"+"\n");
}
catch (IOException e) {
if (debug) System.out.println("Errore risposta server nomi");
if (debug) System.out.println(e);
return -1;
}
return -1;
}
}
lista.add(mess);
try {
os.writeBytes("OK"+"\n");
}
catch (IOException e) {
if (debug) System.out.println("Errore risposta server nomi");
if (debug) System.out.println(e);
return -1;
}
if (debug) System.out.println("Dimensione lista: "+lista.size());
return 0;
}
/**
* Metodo che ritorna l"Ip a partire dal nome dell"utente
* @param os Lo stream di output su cui scrivere l"indirizzo
* Ip richiesto
* @param utente Il nome dell"utente di cui si vuole conoscere l"Ip
* @return Un intero che indica l"esito dell"operazione
*/
public int retrieveIp (DataOutputStream os, String utente) {
String stringa="";
if (debug) System.out.println("Dimensione lista:" + lista.size());
for (int i=0;i<lista.size();i++) {
stringa=(String) lista.get(i);
System.out.println(i+" "+stringa);
String tmp[] = stringa.split(":");
String nome=tmp[0];
if (nome.equals(utente)) {
try {
os.writeBytes(stringa);
}
catch (IOException e) { }
if (debug) System.out.println("TROVATO: " + stringa + " DA:" + utente);
return 0;
}
}
if (debug) System.out.println("NON trovato:" + utente);
try {
os.writeBytes("### Utente " + utente + " offline");
}
catch (IOException e) { }
return -1;
}
/**
* Metodo che restituisce il nome di un utente a partire dall"indirizzo
* Ip
* @param os Lo stream di output su cui scrivere l"indirizzo
* Ip richiesto
* @param ip L"ip dell"utente di cui si vuole conoscere il nome
* @return Un intero che indica l"esito dell"operazione
*/
public int retrieveName (DataOutputStream os, String ip) {
String stringa="";
if (debug) System.out.println("Dimensione lista:" + lista.size());
for (int i=0;i<lista.size();i++) {
stringa=(String) lista.get(i);
System.out.println(i+" "+stringa);
String tmp[] = stringa.split(":");
String ipS=tmp[1];
if (ip.equals(ipS)) {
try {
os.writeBytes(stringa);
}
catch (IOException e) { }
if (debug) System.out.println("TROVATO: " + stringa + " DA:" + ip);
return 0;
}
}
if (debug) System.out.println("NON trovato:" + ip);
try {
os.writeBytes("###<no-name>");
}
catch (IOException e) { }
return -1;
}
/**
* Metodo che disconnette l"utente dal server
* @param nome Il nome dell"utente da disconnettere
*/
public void disconnect(String nome) {
String stringa="";
for (int i=0;i<lista.size();i++) {
stringa=(String) lista.get(i);
System.out.println(i+" "+stringa);
String tmp[] = stringa.split(":");
String nomeS=tmp[0];
if (nome.equals(nomeS)) {
lista.remove(i);
if (debug) System.out.println("TROVATO: " + stringa + " DA:" + nome);
break;
}
}
}
}
/**
* Classe che implementa il server dei nomi. Si occupa di ricevere le
* richieste in ingresso e di avviare i thread per la loro gestione
*/
public class TCPParallelServer {
/**
* Metodo per l"avvio del server
*/
public void start() {
ServerSocket serverSocket=null;
Socket socket=null;
try {
serverSocket = new ServerSocket(5555);
}
catch(IOException e) {
System.out.println("Impossibile avviare la socket - server nomi");
}
System.out.println(serverSocket.getInetAddress().getHostAddress());
System.out.println(serverSocket.getInetAddress().getHostName());
System.out.println(serverSocket);
LinkedList lista=new LinkedList();
//Ciclo infinito di ascolto dei Client
while(true) {
System.out.println("In attesa di chiamate dai Client... ");
try {
socket = serverSocket.accept();
}
catch (IOException e) {
}
System.out.println("Ho ricevuto una chiamata di apertura da:\n" + socket);
ServerThread serverThread = new ServerThread(socket, lista);
serverThread.start();
}
}
/**
* Metodo principale
* @param args nessun argomento da passare
* @throws Exception Eccezione non gestita per l"output
*/
public static void main (String[] args) throws Exception {
TCPParallelServer tcpServer = new TCPParallelServer();
tcpServer.start();
}
}