//Progetto Ingegneria del Software
//Autore: Ignazio Coco
//Matricola: 616/000075
import java.io.*;
import java.net.*;
/**
* Questa classe implementa il lato server dell"applicazione.
* Si occupa di creare un server in ascolto sulla porta 7777 per accettare
* le chiamate esterne
* @author Ezio
*/
public class Listen {
/**
* Questo parametro permette di impostare il programma in modalità
* di debug. Ciò comporta la visualizzazione di tutti i messaggi
* durante la fase di esecuzione
*/
private static boolean debug=false;
/**
* Attributo che identifica la porta su cui il server attende le
* connessioni degli utenti
*/
static int porta=7777;
/**
* Attributo che identifica l"Ip del server dei nomi
*/
static String indIp;
/** Creates a new instance of Listen */
public Listen() {
}
/**
* Metodo per la connessione dell"utente al server dei nomi.
* Questo metodo registra il nome dell"utente sul server dei nomi
* @param nome Indica il nome dell"utente che vuole ricevere messaggi
* @return Ritorna 0, -1, -2 nei casi in cui la connessione abbia
* avuto esito positivo, si abbia un errore generico, l"utente
* è già registrato sul server
*/
public static int connect(String nome) {
Socket socket;
DataOutputStream streamConnOut;
if (debug) System.out.println("Start connect - server nomi");
if (debug) System.out.println("Avvio socket - server nomi...");
try {
socket = new Socket(indIp, 5555);
}
catch (UnknownHostException e) {
if (debug) System.out.println("Errore host sconosciuto - server nomi");
if (debug) System.out.println(e);
return -1;
}
catch (IOException e) {
if (debug) System.out.println("Errore I/O su socket - server nomi");
if (debug) System.out.println(e);
return -1;
}
if (debug) System.out.println("OK");
if (debug) System.out.println("Apertura stream - server nomi...");
try {
streamConnOut = new DataOutputStream(socket.getOutputStream());
streamConnOut.writeBytes("connect:"+nome+ "\n");
if (debug) System.out.println("OK");
if (debug) System.out.println("Chiusura socket e stream - server nomi...");
streamConnOut.close();
socket.close();
if (debug) System.out.println("OK");
}
catch (IOException e) {
if (debug) System.out.println("Errore I/O su stream - server nomi");
if (debug) System.out.println(e);
return -1;
}
if (debug) System.out.println("Socket: "+socket);
if (debug) System.out.println("Stream: "+streamConnOut);
if (debug) System.out.println("OK");
if (debug) System.out.println("Fine connect - server nomi");
return 0;
}
/**
* Il main avvia la connessione al server dei nomi, attente le chiamate
* in ingresso ed avvia un thread per ogni connessione
* @param args Array dei parametri passati da riga di comando.
* Bisogna passare nell"ordine: nome utente, indirizzo IP
* del server dei nomi
*/
public static void main(String args[]) {
String nome = args[0];
indIp = args[1];
ServerSocket serverSocket=null;
if (debug) System.out.println("Avvio connect...");
if (connect(nome)==0) {
if (debug) System.out.println("Connect avvenuta con successo");
}
else {
if (debug) System.out.println("Errore su connect al server dei nomi");
System.exit(-1);
}
if (debug) System.out.println("OK");
try {
if (debug) System.out.println("Tentativo di connessione...");
if (debug) System.out.println("sulla porta : "+porta);
serverSocket = new ServerSocket(porta);
if (debug) System.out.println("OK");
if (debug) System.out.println(serverSocket);
}
catch (IOException e) {
if (debug) System.out.println("Errore avvio socket");
if (debug) System.out.println(e);
System.exit(-1);
}
while (true) {
if (debug) System.out.println("In attesa di connessioni...");
Socket socket=null;
try {
socket = serverSocket.accept();
}
catch (IOException e) {
if (debug) System.out.println("Errore durante l"accept di una socket");
System.exit(-1);
}
if (debug) System.out.println("Ho ricevuto una chiamata di apertura da:\n" + socket);
ListenThread listenThread = new ListenThread(socket, indIp);
listenThread.start();
}
}
}
/**
* Classe per l"implentazione di un thread che gestisce una connessione
* remota
*/
class ListenThread extends Thread {
/**
* Attributo che identifica la socket in ascolto delle nuove connessioni
*/
private Socket socket;
/**
* 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=false;
/**
* Attributo che identifica l"Ip del server dei nomi
*/
String serverLocation;
/**
* Costruttore del thread ListenThread
* @param socket La socket su cui deve operare il thread
* @param serverLocation locazione del server dei nomi
*/
public ListenThread (Socket socket, String serverLocation) {
this.socket = socket;
this.serverLocation = serverLocation;
}
/**
* Metodo che implementa il ciclo di esecuzione del thread
*/
public void run() {
try {
DataInputStream is = new DataInputStream(socket.getInputStream());
InetAddress ind = socket.getInetAddress();
String ip = ind.getHostAddress();
String nome=retrieveName(ip);
if (nome.substring(0,3).equals("###")) nome = "<ERR:no-name>";
String mess;
while (true) {
mess = is.readLine();
if (mess==null) break;
System.out.println(nome+"::"+mess);
}
is.close();
socket.close();
if (debug) System.out.println("Socket Chiuso");
}
catch (IOException e) {
if (debug) System.out.println("Errore su metodo run classe serverthread");
if (debug) System.out.println("IOException: " + e);
}
}
/**
* Metodo per determinare il nome associato all"indirizzo Ip dell"utente
* che si collega a questo server
* @param ip l"Ip di cui determinare il nome
* @return Il nome dell"utente. In caso di errore viene restituita
* una stringa che inizia con ### seguita dalla descrizione
* dell"errore
*/
public String retrieveName (String ip) {
DataOutputStream streamConnOut;
Socket socketForName;
String nome;
int porta;
if (debug) System.out.println("Inizio connect server nomi");
if (debug) System.out.println("Instaurazione socket - server nomi");
try {
socketForName = new Socket(serverLocation, 5555);
}
catch (UnknownHostException e) {
if (debug) System.out.println("Errore host sconosciuto");
if (debug) System.out.println(e);
return "###errore server nomi";
}
catch (IOException e) {
System.out.println("Errore I/O su socket - server nomi");
if (debug) System.out.println(e);
return "###errore server nomi";
}
if (debug) System.out.println("Apertura stream - server nomi");
try {
streamConnOut = new DataOutputStream(socketForName.getOutputStream());
streamConnOut.writeBytes("retrieveName:"+ip + "\n");
DataInputStream is = new DataInputStream(socketForName.getInputStream());
String mess = is.readLine();
String tmp[] = mess.split(":");
if (debug) System.out.println("Messaggio ricevuto: "+mess);
nome=tmp[0];
porta=Integer.parseInt(tmp[2]);
is.close();
streamConnOut.close();
socketForName.close();
return nome;
}
catch (IOException e) {
if (debug) System.out.println("Errore I/O su stream - server nomi");
if (debug) System.out.println(e);
return "###Errore server nomi";
}
}
}