//tale classe(thread) ha il compito di eseguire le richieste accettate e di recuperare i dati richiesti
//sia in un DB locale che inoltrando (se necessario) la richiesta ad altre reti(ai Master di tali reti!)
import java.io.*;
import java.net.*;
import java.util.*;
public class SlaveExeMaster extends Thread{
private int basePort;
private DatagramPacket pacchetto;
private int myIndex;
private DatagramPacket input=null;
private String inRich;
private InetAddress pacAdd;
private DatagramSocket ds=null;
public SlaveExeMaster(int p, DatagramPacket dp){
super("SLAVE" + p);
synchronized(this){
System.out.println("sono dentro al costruttore di: " + new String(dp.getData(), 0, dp.getLength()));
pacchetto=dp;
inRich = new String(pacchetto.getData(), 0, pacchetto.getLength());
pacAdd=pacchetto.getAddress();
ConstantsS.indexS++;
myIndex=ConstantsS.indexS;
basePort=p + 5 + myIndex; //porta udp verso il master da contattare per la risposta
}
}//costruttore
public void run(){
byte[] data;
byte[] buffer = new byte[65507];
DatagramPacket output=null;
try{
Constants.prn(myIndex+"-provo a connettermi su porta: " + basePort);
ds = new DatagramSocket(basePort);
input=new DatagramPacket(buffer, buffer.length);
}
catch (Exception e){
System.out.println(myIndex+"-errore crezione socket per richieste: "+e);
ConstantsS.numRichiesteMaster--;
ConstantsS.ackArrivato.remove(inRich);
ConstantsS.slaveLoad--;
return;
}
//scanno la richiesta x recuperare i campi che mi interessano
//N.B. la richiesta è formata dai 4 campi soliti più la porta UDP dove dovrò rispondere quando avro' finito
try{
//String inRich = new String(pacchetto.getData(), 0, pacchetto.getLength());
System.out.println(myIndex+"-richiesta master: " + inRich);
BufferedReader br1 = new BufferedReader(new StringReader(inRich));
String[] richiesta = new String[4];
String portaMaster="";
int i=0;
String line;
while ((line=br1.readLine())!=null){
if (i<4){
richiesta[i]=line;
}
else{
portaMaster=line;
System.out.println("il Master ha fornito alla richiesta la porta: " + portaMaster);
//dopo che sono arrivato alla portamaster la richiesta è finita, se non lo è do errore!!
if ((line=br1.readLine())!=null){
ConstantsS.numRichiesteMaster--;
System.out.println(myIndex+"-errore numero parametri richiesta Master");
ConstantsS.slaveLoad--;
return;
}
//dopo la portamaster esco xche la richiesta è finita
break;
}
i++;
System.out.println(line);
}
int masterPort=Integer.parseInt(portaMaster);
int ttl=Integer.parseInt(richiesta[3]);
System.out.println(myIndex+"-quando ho finito vado sulla porta: " + masterPort);
Constants.prn(myIndex+"-comincio a lavorare");
//inoltro solo se non è finito il TTL del pacchetto!!!
inoltraQueryMaster iqm=null;
if (ttl>0){
iqm = new inoltraQueryMaster(richiesta, myIndex);
ConstantsS.slaveLoad++;
iqm.start();
//Tale thread inoltra la query e modifica alla fine una variabile in ConstantsS in cui c'è il numero di file reperiti
}
String ris=this.cercaDbLocale(richiesta);
if (iqm!=null){
iqm.join();//attendo che il thread finisca; è bloccante!!!
ConstantsS.slaveLoad--;
}
//debug
//i nomi dei file DEVONO essere cosi:
//i nomi dei file in input sono "indexS-0.dat" fino a "index-numFile.dat"
//File dest = new File(index + "-finito.dat");
fondiFile ff = new fondiFile(ConstantsS.numReperiti + 1, myIndex);//il + 1 rappresenta il file locale
ris=ff.esegui();//in ris ho il nome del file oppure errore
System.out.println(myIndex+"-risultato fondiFile: " + ris);
Constants.prn(myIndex+"-mi sono svegliato");
//la porta TCP è la stessa porta UDP dalla quale lavoro!!!
String msg = "" + ConstantsS.portaSlave;
//come ack che ho finito gli mando la porta dalla quale ascolto i master, cosi' lui controlla su contactSlave con la chiave giusta!!!
data = new byte[msg.length()];
data = msg.getBytes();
System.out.println(myIndex+"-mando l'ack che ho finito su: "+ masterPort);
//DEBUG RIELEZIONE
output=new DatagramPacket(data, data.length, InetAddress.getByName(ConstantsS.masterIP), masterPort);
//output=new DatagramPacket(data, data.length, pacAdd, masterPort);
ds.send(output);
Constants.prn(myIndex+"-attendo su porta: " + basePort);
ds.receive(input);
ServerSocket socket = new ServerSocket(basePort);
Constants.prn(myIndex+"-attendo connessione su serversocket"+ basePort);
Socket s = socket.accept();
Constants.prn(myIndex+"-è arrivata connessione, devo scrivere!!");
BufferedReader inp = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
try {
if (ris!="errore"){
FileReader fis = new FileReader(ris);
BufferedReader br = new BufferedReader(fis);
String inStr;
String parti = inp.readLine();//mi da il via il master
while ( (inStr = br.readLine()) != null){
out.println(inStr);
}
out.println("..");
fis.close();
}
else{
out.println("..");
System.out.println(myIndex+"-scrivo linea: ..");
}
out.flush();
System.out.println(myIndex+"-ho scritto il risultato su: " + out);
String fermati = inp.readLine();
out.close();
inp.close();
System.out.println(myIndex+"-ok, dati scritti su: " + out);
}
catch ( Exception e){
out.println(myIndex+"-errore download file-"+e);
out.flush();
out.close();
inp.close();
}
ConstantsS.numRichiesteMaster--;
ConstantsS.ackArrivato.remove(inRich);
Constants.prn(myIndex+"-muoio");
}
catch (Exception e){
System.out.println(myIndex+"-errore: "+e);
ConstantsS.numRichiesteMaster--;
ConstantsS.ackArrivato.remove(inRich);
ConstantsS.slaveLoad--;
return;
}
}//run
//metodo che cerca nel db locale
private String cercaDbLocale(String[] richiesta){
//cerco localmente e metto il risultato in myIndex-O.dat
//alla fine devo appiccicarci . ".." finali!!!
try{
System.out.println(myIndex+"-Cerco nel db locale...");
File f = new File(myIndex+"-0.dat");
PrintWriter pw = new PrintWriter(new FileWriter(f));
//pw.println(myIndex +"-"+ this.getName() +"-"+ richiesta[0] + "-" + richiesta[1] + "-" + richiesta[2] + "-" + richiesta[3] + "-");
System.out.println("Index: " + myIndex +";Nodo: "+ ds.getLocalAddress().getLocalHost().toString() + "Thread: "+ this.getName()+"; Richiesta: "+ richiesta[0] + "-" + richiesta[1] + "-" + richiesta[2] + "-" + richiesta[3]);
pw.println("Index: " + myIndex +";Nodo: "+ ds.getLocalAddress().getLocalHost().toString() + "Thread: "+ this.getName()+"; Richiesta: "+ richiesta[0] + "-" + richiesta[1] + "-" + richiesta[2] + "-" + richiesta[3]);
pw.flush();
pw.close();
}
catch (Exception e){
}
return "";
}
}//class