Marco Ronchetti ronchetdit unitn it 2002 Basi di
Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 “Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento J 0 1 Java Networking TCP
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Sockets J 0 2 Java supporta un accesso semplificato e object-oriented alle sockets. Questo rende la network comunicazione di rete sensibilmente piu’ semplice. Molto piu’ semplice che in C++!! Vedremo che parlare ad un altra applicazione (locale o remota) puo’ essere semplice come leggere un file o ottenere un input da un utente.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Clients and Servers J 0 3 Quando si scrivono network applications, e’ comune parlare di clients e servers. La distinzione e’ piuttosto vaga, ma sostanzialmente possiamo pensare che : • chi inizia la conversazione e’ il client. • chi accetta la richiesta di parlare e’ il server. Per I nostri scopi, la piu’ importante differenza tra client e server e’ che il client puo’ in qualunque istante creare una socket per iniziare una conversazione con una server application, mentre un server si deve preparare ad ascoltare in anticipo per possibili conversazioni in arrivo.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Sockets J 0 4 La java. net. Socket class rappresenta un singolo lato di una connessione socket indifferentemente su un client o su un server. Inoltre, il server usa la java. net. Server. Socket class per attendere connessioni da clients. Un applicazione agente come server crea un Server. Socket object e attende, bloccato in una chiamata al suo metodo accept(), finche’ non giunge una connessione. A quel punto, il metodo accept() create un Socket object che il server usa per comunicare con il client.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Sockets J 0 5 Un server mantiene molte conversazioni simultaneamente. C’e’ una sola Server. Socket, ma una oggetto Socket attivo per ogni cliente.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Server port J 0 6 Un client ha bisogno di due informazioni per connettersi a un server su Internet: un nome di host (per recuperare l’indirizzo del server) e un numero di porta (per individuare il processo sulla macchina server). Una applicazione server ascolta su una porta predefinita mentre attende una connessione. I clients selezionano il numero di porta corrispondente al servizio desiderato. I numeri di porta sono codificati nelle RFC (Es. Telnet 23, FTP 21, ecc. ), ma possono anche essere scelti (quasi) arbitrariamente per applicazioni custom.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Client port J 0 7 Il numero di porta del client e’ tipicamente assegnato dal sistema operativo: la scelta di tale numero non e’ di solito rilevante. Quando una client socket mand un pacchetto a una server socket, il pacchetto include la specifica della porta e dell’indirizzo del cliente: cosi’ il server e’ in grado di rispondere.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Sockets J 0 8 Usando le sockets, si deve decidere che tipo di protocollo si desidera per il trasporto di pacchetti sulla rete: Un protocollo connection-oriented o Un protocollo connectionless.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Connection-oriented protocols J 0 9 Un protocollo connection-oriented offre l’equivalente di una conversazione telefonica. • Dopo aver stabilito la connessione, due applicazioni possono scambiarsi dati. • La connessione rimane in essere anche se nessuno parla. Il protocollo garantisce che non vengano persi dati e che questi arrivino sempre nell’ordine corretto. La classe Java Socket usa un protocollo connectionoriented, e “parla” TCP
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Connectionless Protocols J 0 10 Un protocollo connectionless somiglia al servizio postale. Le applicazioni possono inviarsi brevi messaggi, ma non viene tenuta aperta una connessione tra un messaggio e l’altro. Il protocollo NON garantisce che non vadano persi dati e che ne’ che questi arrivino nell’ordine corretto. La classe Datagram. Socket usa un protocollo connectionless, e “parla” UDP
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Connection oriented Protocols J 0 11 Con un connection-oriented protocol, una client socket stabilisce, alla sua creazione, una connessione con una server socket. Stabilita la connessione, un protocollo connection-oriented assicura la consegna affidabile dei dati, ovvero: 1. Ogni pacchetto spedito, il pacchetto viene consegnato. Ad ogni spedizione, la socket si aspetta di ricevere un acknowledgement cheil pacchetto e’ stato ricevuto con sucesso. Se la socket non riceve l’acknowledgement entro un tempo prestabilito, la socket ri-invia il pacchetto. La socket continua a provare finche’ la trasmissione ha successo, o finche’ decide che la consegna e’ impossibile.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Connection oriented Protocols J 0 12 2. I paccheti sono letti from dalla socket ricevente nello stesso ordine in cui sono stati spediti. Per il modo in cui la rete funziona, i pacchetti possono arrivare alla socket destinataria in un ordine diverso da quello in cui sono stati spediti. Un protocollo reliable, connection-oriented permette alla socket ricevente di riordinare i paccheti ricevuti, cosi’ che possano essere letti dal programma ricevente nell’orine in cui erano stati spediti.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 java. net. Socket J 0 13 Questa classe implementa una socket per interprocess communication over the network. I constructor methods creano la socket e la connettono allo host e porta specificati.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 java. net. Socket J 0 14 Una volta creata la socket, get. Input. Stream() e get. Output. Stream() ritornano oggetti Input. Stream e Output. Stream che possono essere usati come se fossero canali di I/O su file. get. Inet. Address() e get. Port() restituicono indirizzo e porta a cui la socket e’ connessa. get. Local. Port() ritorna la porta locale usata dalla socket.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 java. net. Server. Socket J 0 15 Questa classe e’ usata dai servers per ascoltare le richieste di connessione. Quando si crea una Server. Socket, si specifica su quale porta si ascolta. Il metodo accept() iniza ad ascoltare su quella porta, e si blocca finche’ un client non richiede una connessione su quella porta. A quel punto, accept() accetta la connessione, creando e ritornando una Socket che il server puo’ usare per comunicare col client.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Sockets J 0 16 Clients Un applicazione client apre una connessione con un server costruendo una Socket che specifica hostname e port number del server desiderato: try { Socket sock = new Socket(“www. pippo. it", 80); //Socket sock = new Socket("128. 252. 120. 1", 80); } catch ( Unknown. Host. Exception e ) { System. out. println("Can't find host. "); } catch ( IOException e ) { System. out. println("Error connecting to host. "); }
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Connection-oriented protocol J 0 17 Il lato server di un protocollo connection-oriented tipicamente esegue questa sequenza: • Crea un Server. Socket object per accettare connessioni. • Quando il Server. Socket accetta la connection, crea un oggetto Socket che encapsula la connessione. • Alla Socket viene chiesto di creare oggetti Input. Stream e Output. Stream che leggono e scrivono bytes da e verso la connessione. • La Server. Socket puo’ opzionalmente creare una nuova thread per ogni connessione, cosi’ che il server possa ascoltare per nuove connessioni mentre serve i clienti gia’ acquisiti.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Reading & Writing raw bytes – Client side J 0 18 Una volta stabilita la connessione, input e output streams possono essere ottenuti con i metodi get. Input. Stream() e get. Output. Stream() di Socket. try { Socket server = new Socket("foo. bar. com", 1234); Input. Stream in = server. get. Input. Stream(); Output. Stream out = server. get. Output. Stream(); // Write a byte out. write(42); // Read a byte Byte back = in. read(); server. close(); } catch (IOException e ) { }
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Reading & Writing newline delimited strings – Client J 0 19 Incapsulando Input. Stream & Output. Stream e’ possibile accedere agli streams in modo piu’ semplice. try { Socket server = new Socket("foo. bar. com", 1234); Input. Stream in = server. get. Input. Stream(); Data. Input. Stream din = new Data. Input. Stream( in ); Output. Stream out = server. get. Output. Stream(); Print. Stream pout = new Print. Stream( out ); // Say "Hello" (send newline delimited string) pout. println("Hello!"); // Read a newline delimited string String response = din. read. Line(); server. close(); } catch (IOException e ) { }
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Reading & Writing raw bytes – Server side Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 try { J 0 20 Server. Socket listener = new Server. Socket( 1234 ); while ( !finished ) { Socket a. Client = listener. accept(); // wait for connection Input. Stream in = a. Client. get. Input. Stream(); Output. Stream out = a. Client. get. Output. Stream(); // Read a byte Byte important. Byte = in. read(); // Write a byte out. write(43); a. Client. close(); } listener. close(); } catch (IOException e ) { }
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Reading & Writing newline delimited strings – Server Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 try { J 0 21 Server. Socket listener = new Server. Socket( 1234 ); while ( !finished ) { Socket a. Client = listener. accept(); // wait for connection Input. Stream in = a. Client. get. Input. Stream(); Data. Input. Stream din = new Data. Input. Stream( in ); Output. Stream out = a. Client. get. Output. Stream(); Print. Stream pout = new Print. Stream( out ); // Read a string String request = din. read. Line(); // Say "Goodbye" pout. println("Goodbye!"); a. Client. close(); } listener. close(); } catch (IOException e ) { }
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento This server is single-threaded Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Questo server e’ single-threaded J 0 22 Tratta una sola connessione alla volta; non chiama accept() per ascoltare nuove connessioni fin quando non ha finito con quella corrente. Un server piu’ realistico avrebbe un loop che accetta connessioni e le passa ad altre thread per servirle concorrentemente.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 What about the Little Endian/Big Endian issue? J 0 23 Le classi Java Data. Input. Stream and Data. Output. Stream lavorano con i bytes di tipi interi in network byte order (most significant to least significant). Percio’ non c’e’ necessita’ di conversione dei dati!
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Limitations J 0 24 Applets e altre applicazioni che girano sotto il controllo del Security. Manager possono avere restrizioni arbitrarie su quali hosts possono raggiungere, e sul fatto di poter accettare connessioni. La security policy standard imposta dai browsers premette alle applets di aprire socket solo con lo host da cui provengono. Le applets hanno il permesso di aprire server sockets.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Limitations J 0 25 Ora, questo non significa che una applet non possa cooperare con il suo server per comunicare con chiunque e ovunque. Il server può girare un proxy che permette alla applet di comunicare indirettamente con chiunque. Questo pone l’onere del controllo della sicurezza sul server originante, e non sulla macchina client.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Un mini-server concorrente HTTP – Introduz. J 0 26 Tiny. Httpd ascolta su una port specificata and serve semplici richieste HTTP "get file“: GET /path/filename [optional stuff] Il Web browser manda una o piu’ di queste linee per ogni documento da ottenere. Letta la richiesta, il server prova ad aprire il file specificato e ne spedisce il contenuto. Se il documento contiene referenze ad immagini o altro da mostrare online, il browser continua con richieste GET addizionali. Per ragioni di performance, Tiny. Httpd serve ogni richiesta in una sua thread. Percio’ Tiny. Httpd puo’ servire molte richieste concorrentemente.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Un mini-server concorrente HTTP J 0 27 import java. net. *; import java. io. *; import java. util. *; public class Tiny. Httpd { public static void main( String argv[] ) throws IOException { Server. Socket ss = new Server. Socket(Integer. parse. Int(argv[0])); while ( true ) new Tiny. Httpd. Connection( ss. accept() ); } }
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Un mini-server concorrente HTTP Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 class Tiny. Httpd. Connection extends Thread { Socket sock; Tiny. Httpd. Connection ( Socket s ) { sock = s; set. Priority( NORM_PRIORITY - 1 ); start(); } public void run() { try { Output. Stream out = sock. get. Output. Stream(); Data. Input. Stream d=new Data. Input. Stream(sock. get. Input. Stream()); String req = d. read. Line(); System. out. println( "Request: "+req ); String. Tokenizer st = new String. Tokenizer( req ); J 0 28
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Un mini-server concorrente HTTP Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 if ( (st. count. Tokens() >= 2) && st. next. Token(). equals("GET") ) { if ( (req = st. next. Token()). starts. With("/") ) req = req. substring( 1 ); if ( req. ends. With("/") || req. equals("") ) req = req + "index. html"; try { File. Input. Stream fis = new File. Input. Stream ( req ); byte [] data = new byte [ fis. available() ]; fis. read( data ); out. write( data ); } catch ( File. Not. Found. Exception e ) new Print. Stream( out ). println("404 Not Found"); } else new Print. Stream( out ). println( "400 Bad Request" ); sock. close(); } catch ( IOException e ) System. out. println( "I/O error " + e ); } J 0 29 }
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Un mini-server concorrente HTTP - uso Compila Tiny. Httpd e mettilo nel tuo class path. Vai in una directory con qualche documento interessante e avvia il daemon, specificando un numero di porta non usato come argomento. Per esempio: % java Tiny. Httpd 1234 Ora dovrebbe essere possibile usare un Web browser standard per ottenere i files dal tuo host. Nella URL dovra’ essere specificato il numero di porta scelto. Per esempio, se il tuo hostname e’ xx. science. unitn. it, ed hai avviato il server come sopra, sara’ possibile ottenere il file welcome. html con: http: //xx. science. unitn. it: 1234/welcome. html J 0 30
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Un mini-server concorrente HTTP - Note J 0 31 Abbassando la sua priorita’ a NORM_PRIORITY-1, assicuriamo che la threads che serve le connessioni gia’ stabilite non blocchi la main thread di Tiny. Httpd impedendole di accettare nuove richieste.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Un mini-server concorrente HTTP - Problemi J 0 32 Tiny. Httpd ha un sacco di possibilita’ di miglioramento! Primo: consuma un sacco di memoria allocando un array enorme per leggere un intero the file tutto d’un colpo. Un’implementazione piu’ realistica userebbe un buffer ed invierebbe i dati in piu’ passei. Tiny. Httpd inoltre non riconosce semplici directories. Non sarebbe difficile aggiungere alcune lineee per leggere directories e generare liste di link HTML come fanno molti web server.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Un mini-server concorrente HTTP - Problemi J 0 33 Tiny. Httpd soffre di limitazioni imposte dalla debolezza di accesso al filesystem. E’ importante ricordare che le pathnames sono architecture dependent—cosi’ come il concetto stesso di filesystem. Tiny. Httpd funziona, cosi’ com’e’, su systemi UNIX e DOSlike, ma richiede alcune variazioni su altre piattaforme. E’ possibile scrivere del codice piu’ elaborato code che usa environmental information offerte da Java per adattarsi al sistema locale.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Un mini-server concorrente HTTP - Problemi J 0 34 Il problema principale con Tiny. Httpd e’ che non ci sono restrizioni sui files a cui puo’ accedere. Con qualche trucco, il daemon spedirebbe un qualunque file del suo filesystem al client. Sarebbe utile rlimitare Tiny. Httpd ai files che sono nella directory corrente, or una subdirectory.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento mini-server concorrente HTTP – Security Manager Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 import java. io. *; J 0 35 class Tiny. Httpd. Security. Manager extends Security. Manager { public void check. Access(Thread g) { }; public void check. Listen(int port) { }; public void check. Link(String lib) { }; public void check. Property. Access(String key) { }; public void check. Accept(String host, int port) { }; public void check. Write(File. Descriptor fd) { }; public void check. Read( String s ) { if ( new File(s). is. Absolute() || (s. index. Of(". . ") != -1) ) throw new Security. Exception ("Access to file : "+s+" denied. "); } }
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento mini-server concorrente HTTP – Security Manager Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 Il cuore di questo security manager e’ il metodo check. Read(). J 0 36 Controlla due cose: assicura che il pathname non sia assoluto, e che il pathname non contenga un double dot (. . ) che risale l’albero delle directories. Con questi vincoli siamo certi (almeno su un filesystem UNIX o DOS-like) di aver ristretto l’accesso alle solo subdirectories della directory corrente. Se il pathname e’ absolute o contiene ". . ", check. Read() lancia una Security. Exception.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 mini-server concorrente HTTP – Security Manager J 0 37 Gli altri metodi che non fanno nulla --e. g. , check. Access()— permettono al daemon di fare il suo lavoro senza interferenza da paret del security manager. Quando installiamo un security manager, ereditiamo implementazioni di molte "check" routines. L’implementazione default non permette di fare nulla; Lancia una security exception appena chiamata. Dobbiamo aprire dei buchi cosicche’ il daemon possa fare il suo lavoro; deve accettare connections, ascoltare sockets, creare threads, leggere property lists, ecc. Per questo sovrascriviamo i metodi default.
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 mini-server concorrente HTTP – Security Manager J 0 38 Per installare il security manager, aggiungere la seguente riga all’inizio del main di Tiny. Httpd: System. set. Security. Manager( new Tiny. Httpd. Security. Manager() ); Per catturare le security exception, aggiungere il seguente catch dopo la catch di File. Not. Found. Exception': catch ( Security. Exception e ) new Print. Stream( out ). println( "403 Forbidden" );
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 A simple e-mail client J 0 39 import java. net. *; import java. io. *; import java. util. *; class EMail. Client{ public static void main(String[] args){ new Email. Client() } // end main EMail. Client() { String server = "put your email server name here"; int port = 25; //mail port try{ //Get a socket, connected to the specified server // on the specified port. Socket socket = new Socket(server, port);
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 A simple e-mail client J 0 40 //Get an input stream from the socket Buffered. Reader input. Stream = new Buffered. Reader(new Input. Stream. Reader( socket. get. Input. Stream())); //Get an output stream to the socket. Note // that this stream will autoflush. Print. Writer output. Stream = new Print. Writer(new Output. Stream. Writer( socket. get. Output. Stream()), true); //Begin the conversation with the email server. output. Stream. println( "mail from: put your email name here"); System. out. println(input. Stream. read. Line()); output. Stream. println( "rcpt to: " + "put your email name here"); System. out. println(input. Stream. read. Line()); output. Stream. println("data"); System. out. println(input. Stream. read. Line());
“Basi di Dati Web e Distribuite” – Laurea Specialitica in Informatica – Università di Trento Marco Ronchetti - ronchet@dit. unitn. it Ó 2002 A simple e-mail client J 0 41 String time. Stamp = (new Date()). to. String(); output. Stream. println("Test message " + time. Stamp); output. Stream. println(". "); System. out. println(input. Stream. read. Line()); //Close the socket. close(); }//end try catch(Unknown. Host. Exception e){ System. out. println(e); System. out. println( "Must be online to run properly. "); }//end catch Unknown. Host. Exception catch(IOException e){System. out. println(e); } }//end constructor }//end class
- Slides: 41