ProgettAzione tecnologie in movimento - V anno Unità 4 - Realizzare applicazioni per la comunicazione in rete Compito in classe proposto Realizzare un’applicazione C/S per trasferire al Client il contenuto di una pagina web scaricata dal Server. Si dovranno scrivere due programmi: • un programma Server che si mette in ascolto (ciclo infinito) su una porta prestabilita per questo servizio e, quando arriva la richiesta del Client, provvede a salvare in locale in un file html la pagina richiesta e successivamente a inviare il file al Client; • un programma Client che introduce da tastiera la stringa contenente l’indirizzo http desiderato, invia la richiesta al Server e si mette in ascolto della risposta per poi salvare in locale il file ricevuto. Unità 4 - Realizzare applicazioni per la comunicazione in rete Soluzione compito in classe proposto Realizziamo il servizio di download richiesto attraverso la scrittura di due programmi distinti: • un programma ServerURL di tipo Server che si mette in ascolto su una porta prestabilita per quel servizio e, quando arriva la richiesta del Client, provvede a salvare in locale la pagina richiesta in un file html e di seguito a inviarne copia al Client; • un programma ClientURL di tipo Client che introduce da tastiera la stringa contenente l’indirizzo http, invia la richiesta al Server e si predispone a ricevere e salvare la copia del file html inviatogli dal Server. I due programmi, nel loro funzionamento abituale, devono essere eseguiti su due macchine diverse. E’ comunque possibile, per chi non disponesse di una rete o delle eventuali autorizzazioni, simulare il funzionamento dei due programmi in modalità stand-alone mandandoli in esecuzione parallelamente su un unico elaboratore. L’indirizzo web (HTTP) viene gestito attraverso la classe URL. Per scaricare il contenuto dell'URL usiamo direttamente il metodo della classe URL openStream(). La comunicazione tra il Client e il Server la realizziamo creando uno stream sulla porta 2000 del Server (Figura 1) utilizzando il protocollo TCP e dunque appoggiandoci alle classi ServerSocket e Socket contenute nel package java.net. localport random Viene inoltre utilizzata la classe InetAddress (sempre contenuta nel medesimo package) per gestire l’indirizzo IP. La sequenza di passi che realizza la comunicazione tra i due processi è la seguente: 1. … Server in ascolto sulla porta 2000 2. Client invia la richiesta contenente l’URL sulla porta 2000 del Server 3. Server scarica la pagina dal web e la salva su file html in locale (C:/Server/compito.html) 4. Client in attesa sulla porta 2000 della copia del file html scaricato dal Server 5. Server invia al Client copia del file html scaricato 6. Client salva in locale copia del file html ricevuto (C:/Client/compito.html) e chiude la © Mondadori Education ProgettAzione tecnologie in movimento - V anno Soluzione compito in classe proposto connessione 7. Server in ascolto sulla porta 2000 … Codice Java per la parte CLIENT (ClientURL) ClientURL.java import java.net.*; import java.io.*; import java.util.InputMismatchException; import java.util.Scanner; public class ClientURL { public static void main(String[] arg) { // Porta del Server: utilizzare una porta maggiore di 1023 int portS=2000; // Oggetto da utilizzare per la comunicazione Socket connection; // Indirizzo del Server TCP InetAddress serverAddress; //stream per gestire il flusso di output OutputStream outSocket; PrintWriter streamOut; String tastiera; try { /* Usare getLocalHost() se il Server è sulla stessa macchina del Client altrimenti occorre conoscere l'IP del Server */ serverAddress = InetAddress.getLocalHost(); System.out.println("Indirizzo del server trovato"); connection = new Socket(serverAddress, portS); System.out.println("Connessione aperta"); outSocket = connection.getOutputStream(); streamOut = new PrintWriter(outSocket); System.out.println("Introduci l'URL: (ESEMPIO http://java.sun.com) "); // Introduce da tastiera l’URL e lo invia al Server: Scanner scanString = new Scanner(System.in); tastiera=""; try { tastiera=scanString.nextLine(); scanString.close(); } catch (InputMismatchException iMex) { System.err.println(iMex); © Mondadori Education ProgettAzione tecnologie in movimento - V anno Unità 4 - Realizzare applicazioni per la comunicazione in rete } streamOut.println(tastiera); streamOut.close(); connection.close(); System.out.println("Richiesta inviata"); System.out.println("Client in attesa di trasferimento file sulla porta " + portS + "\n"); connection = new Socket(serverAddress, portS); try { System.out.println("Richiesta trasferimento ricevuta da " + connection); // Intercetto il flusso in arrivo cioè il file inviato dal Client: ObjectInputStream inputStream = new ObjectInputStream(connection.getInputStream()); // Eseguo un cast dell'oggetto ricevuto in tipo File: File in = (File) inputStream.readObject(); /* Estraggo il nome originale del file ricevuto e predispongo un file di output: */ File out = new File("C:/Client/" + in.getName()); // Lancio il metodo che esegue il salvataggio sul Server: System.out.println(" --ricezione file " + in.getName()); System.out.println(" --dimensione file " + in.length()); // Apro uno stream di input sul file che e' stato inviato: FileInputStream inStream = new FileInputStream(in); // Apro uno stream di output per il salvataggio del nuovo file FileOutputStream outStream = new FileOutputStream(out); // Preparo il buffer per contenere una riga del file: byte[] buf = new byte[1024]; /* leggo, una riga per volta, il file originale (dallo stream di input) e lo scrivo nel file destinazione (nello stream di output): */ int i; while((i=inStream.read(buf))!=-1) { outStream.write(buf, 0, i); } // Chiudo gli streams: inStream.close(); outStream.close(); System.out.println(" --ricezione completata"); } catch (Exception e) { e.printStackTrace(); } connection.close(); System.out.println("Connessione chiusa"); } catch (IOException e) { System.err.println(e); } } } © Mondadori Education ProgettAzione tecnologie in movimento - V anno Soluzione compito in classe proposto Codice Java per la parte SERVE (ServerURL) ServerURL.java import java.net.*; import java.io.*; import java.util.Scanner; import java.io.IOException; public class ServerURL { public static void main(String[] arg) { // Porta del Server: utilizzare una porta maggiore di 1023 int portS=2000; // Socket TCP ServerSocket sSocket; // Oggetto da utilizzare per la comunicazione: Socket connection; // Stream per gestire il flusso di input: InputStream inSocket; Scanner streamIn; String messageIn; System.out.println("Apertura porta in corso"); try { sSocket = new ServerSocket(portS); while (true) { System.out.println("Server in ascolto sulla porta " + portS + "\n"); connection = sSocket.accept(); System.out.println("Connessione stabilita"); // Estrae il messaggio ricevuto, lo mostra e poi chiude lo stream: inSocket = connection.getInputStream(); streamIn = new Scanner(inSocket); messageIn = streamIn.nextLine(); streamIn.close(); System.out.print("URL ricevuto: "); System.out.println(messageIn); connection.close(); System.out.println("Connessione chiusa"); try { // Crea un oggetto della classe URL: URL indirizzoWeb = new URL(messageIn); // Salva il contenuto della pagina web in un file locale del Server: InputStream in = new BufferedInputStream(indirizzoWeb.openStream()); © Mondadori Education ProgettAzione tecnologie in movimento - V anno Unità 4 - Realizzare applicazioni per la comunicazione in rete OutputStream out = new BufferedOutputStream(new FileOutputStream("C:/Server/compito.html")); int readbyte = in.read(); while (readbyte >= 0) { out.write(readbyte); readbyte = in.read(); } in.close(); out.close(); File file = new File ("C:/Server/compito.html"); System.out.println("Server pronto a inviare file sulla porta " + portS + "\n"); connection = sSocket.accept(); System.out.println("Connessione stabilita"); ObjectOutputStream outputStream = new ObjectOutputStream(connection.getOutputStream()); outputStream.reset(); outputStream.writeObject(file); outputStream.flush(); outputStream.close(); System.out.println("File inviato"); } catch (IOException e) { /* IN CASO DI ERRORE VIENE TRASFERITO UN FILE ALARM.TXT PRECEDENTEMENTE PREDISPOSTO IN SOSTITUZIONE DI COMPITO.HTML */ System.err.println(e); File file = new File ("C:/Server/alarm.txt"); System.out.println("Server pronto a inviare alarm sulla porta " + portS + "\n"); connection = sSocket.accept(); System.out.println("Connessione stabilita"); ObjectOutputStream outputStream = new ObjectOutputStream(connection.getOutputStream()); outputStream.reset(); outputStream.writeObject(file); outputStream.flush(); outputStream.close(); System.out.println("File alarm inviato"); } connection.close(); System.out.println("Connessione chiusa"); } // Fine while } catch (IOException e) { System.err.println(e); } } // Fine main } // Fine classe ServerURL © Mondadori Education ProgettAzione tecnologie in movimento - V anno Soluzione compito in classe proposto I programmi sono stati provati con Eclipse Standard/SDK - Version: Kepler Release © Mondadori Education ProgettAzione tecnologie in movimento - V anno