Torna alla pagina di Sistemi per l'elaborazione delle informazioni
:: A lezione con Ceravolo! ::
ovvero Protocolli applicativi - Application Layer
Indice
Sono applicazioni distribuite, ovvero eseguiti su una macchina locale ma che interagiscono con una macchina posta altrove sulla rete. Esempi di questi protocolli sono: server Email su internet, Msn, Emule, VoIp ecc...
Ci sono tipi diversi di applicazioni distribuite:
Un processo è un qualunque programma che funziona su un host, sia lato client che lato server. Il sistema operativo gestisce i processi e la IPC (Inter Process Communication). Come collegare tra loro processi diversi? Tramite la nozione di porta. Una porta è un concetto astratto per stabilire che il processo X, che sarà interrotto da altri processi, possa comunicare con il processo Y, il quale parimenti sarà interrotto e così via. Sostanzialmente per porta si intende quindi un canale di comunicazione attraverso cui due host riescono a comunicare.
Per gestire la comunicazione dei processi fra host diversi uso i socket. A cosa mi servono le porte allora? Beh, non posso tener conto solo del fatto che ogni host ha un indirizzo IP unico, perchè processi diversi possono essere inviati sullo stesso terminale. Devo quindi associare un numero di porta per distinguerli (eg il numero di porta di internet solitamente è 80).
Le porte note (well known ports, per dirlo alla francese) sono delle porte dai valori compresi tra lo 0 e il 1023, che lo IANA (Internet Assigned Numbers Authority) ha associato a specifici servizi TCP e/o UDP. Tra le più importanti ricordiamo:
Porta | Servizio |
20 /tcp | FTP (data) |
21 /tcp | FTP (controllo) |
23 /tcp | Telnet |
25 /tcp | SMTP |
53 /tcp/udp | DNS |
80 /tcp | HTTP |
110 /tcp | POP3 |
143 /tcp | IMAP4 |
Solitamente il protocollo definisce espressamente le prime due cose, la terza è implicita.
In base a ciò che un'applicazione richiede si caratterizza il protocollo:
Eg: per il trasferimento dei file non dovrò avere perdita di dati, poco tempo di attesa e una banda elastica in base alla quantità di dati da trasferire.
TCP | UDP | ||
connessione | NO connessione | ||
controllo flusso | NO controllo flusso | ||
controllo congestione | NO congestion control | ||
NO timing | NO timing | ||
NO banda minima | NO banda minima |
Ma se UDP non fa un cavolo, che utilità ha? Beh, innanzitutto è un protocollo più leggero (intestazione di 8 byte) e quindi comporta un basso consumo di banda. Poi il fatto di non creare alcuna connessione elimina i ritardi dovuti alla configurazione della comunicazione (non ci sono partecipanti da sincronizzare).
Le pagine web come tutti sappiamo sono composte da un gran numero di oggetti: un file html di base contiene infatti riferimenti ad altri oggetti: immagini jpg, applet java ecc... Ogni oggetto è indirizzabile con un URL: eg. "www.someschool.edu/someDept/pic.gif" identificherà il nome di un'immagine.
Attenzione! Ci sono delle differenze quando di parla di URL, URI e URN!
Una URI può essere rappresentata in forma di URL, URN o una combinazione di entrambi.
Applicazione Web. Il client invia una richiesta di un oggetto, identificato con un URI: il server se ce l'ha lo invia, altrimenti risponde con un errore. Semplice vero?
Ne esistono due versioni diverse: la 1.0 e la 1.1 (come GDA d'altronde).
L'HTTP si basa su TCP: il client richiede dati aprendo una connessione TCP al server sulla porta 80; quando ho ottenuto le informazioni che mi servono, la connessione si chiude. Per ogni oggetto invio una richiesta.
E' semplice da gestire, sia lato client che lato server, e questa è stata la base del successo iniziale del web.
E' un protocollo senza stati, cioè la connessione viene aperta e chiusa ogni volta; il server non tiene memoria delle richieste precedenti, perciò se non mi arriva un oggetto dovrò ripetergliela.
Dato però che questa semplicità eccessiva non permetteva di gestire la persistenza della connessione (e per altri motivi), si è passati alla versione 1.1 con il vantaggio che riesco a mandare più oggetti con una singola connessione, risparmiando banda.
Attenzione! Mantenere la connessione aperta non significa avere gli stati.
Nell' HTTP 1.0:
Quant'è perciò il tempo di risposta? C'è un RTT per aprire la connessione, un RTT per la richiesta HTTP e i primi bytes della risposta, infine il tempo di trasmissione dei file.
TOTALE = 2RTT + tempo di trasmissione per ogni oggetto.
Ecco perchè sorge la necessità di un HTTP persistente.
Ci sono due implementazioni di persistenza:
Ho due messaggi HTTP: REQUEST e RESPONSE
E' in ASCII ed è composto da tre parti:
I metodi che possono apparire nella request line sono i seguenti, divisi per versione del protocollo:
HTTP 1.0 | HTTP 1.1 | Descrizione |
GET | GET | Serve a richiedere dati al server, la risposta finisce nell'URL/URI (tanti server mandano le variabili direttamente nell'URI, con un vantaggio per il copia e incolla - ad esempio i file di youtube con il ?= - ma uno svantaggio perché sono in chiaro). |
POST | POST | Serve a richiedere dati al server, ma in questo caso la risposta finisce nel body. |
HEAD | HEAD | Non chiede tutto l'oggetto ma solo l'intestazione (eg. per conoscere quando è stato aggiornato l'oggetto). |
PUT | Per l'upload dei file. | |
DELETE | Per cancellare file dal server. |
Anch'essi composti da tre parti:
GET /wiki HTTP/1.1 Host: doppioclic.altervista.org Connection: Close User-Agent: Mozilla/5.0 Accept: text/html, image/jpeg, image/png, text/*, image/*, */* Accept-Encoding: x-gzip, x-deflate, gzip, deflate, identity Accept-Charset: iso-8859-1, utf-8;q=0.5, *;q=0.5 Accept-Language: itHTTP RESPONSE MESSAGE:
HTTP/1.1 301 Moved Permanently Date: Fri, 18 Jan 2008 20:56:52 GMT Server: Apache Location: http://doppioclic.altervista.org/wiki/ Vary: Accept-Encoding Content-Length: 246 Connection: close Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head ... ecc ecc
Per simulare uno stato nell'HTTP vengono usati i Cookies.
Eg. ho un sito che vende ciarpame e voglio mantenere un carrello della spesa per un utente. Dato che HTTP non ha memoria, scrivo le informazioni su file detti cookies. Posso dunque usarli per:
Se serve un cookie, quando il server risponde aggiungerà una linea nell'header (ad esempio) "Set-cookie:1678" ed il client dovrà mantenerlo in memoria. Quando poi il client invierà successive richieste, manderà anche "cookie: 1678" così che il server sappia chi sono.
E' tutto bello e comodo, ma sorgono però dei problemi di privacy, dato che questi file contengono informazioni più o meno riservate sul mio conto.
Per migliorare l'efficienza della rete è meglio ridurre il numero di richieste sui server. Si utilizzano così dei dispositivi chiamati proxy che provvedono a fare da tramite e che mantengono nella loro cache una copia degli oggetti richiesti, così da mandar questi invece di richiederli dai server. Certo, in questo modo un proxy dovrà sempre controllare che l'oggetto nella cache sia aggiornato, ed ecco quindi a cosa serve il campo date dello header HTTP. (Attenzione! l'aggiornamento non viene fatto ogni volta, o il risparmio di traffico sarebbe relativo)
Il server a cui viene chiesto di controllare se l'oggetto sia stato aggiornato risponde 304 se non lo è, con una data altrimenti.
File Transfer Protocol. Attivo sulla porta 21, apre due connessioni: una per il controllo e una per il trasferimento dati. Problemi:
E' persistente perciò la connessione viene tenuta aperta e si mantiene una sessione. Meglio ancora: è la connessione per il controllo del trasferimento che rimane aperta per tutta la sessione, mentre quella del trasferimento vero e proprio si apre e si chiude per ogni file trasferito.
Per autenticarsi occorre mandare username e password.
I comandi FTP sono delle stringhe di caratteri ASCII, che richiedono l'inserimento di una USER e di una PASSword per ogni sessione. Alcuni comandi:
Di seguito alcuni codici di ritorno dell'FTP:
Esistono tre componenti principali:
...e tre fasi di comunicazione:
Il messaggio viene passato in codifica ASCII.
Passaggi:
Il client si presenta con il comando HELLO:
client: MAIL FROM <address@server.extension> server: 250 server ok client: RCPT TO <....@....> server: recipient ok client: DATA server: 354 Enter mail client: ...inizio email....
Le email sono terminate da un punto messo in una riga da solo. La connessione viene aperta e chiusa alla fine del messaggio. Si può eseguire il tutto da telnet sulla porta 25.
Alla fine si saluta scrivendo QUIT
.
Riassumendo i comandi principali di un messaggio in SMTP sono: HELO, MAIL FROM, RCPT TO, DATA, QUIT.
SMTP viene usato anche tra server e server per l'invio effettivo di mail. NON c'è bisogno di autenticazioni.
Il MIME (Multipurpose Internet Mail Extensions) è uno standard che estende il formato delle e-mail, consentendo di inviare altri tipi di informazione oltre al testo ASCII, come ad esempio testi scritto in lingue diverse dall'Inglese, immagini, suoni e filmati, o anche programmi.
Gli headers aggiuntivi del MIME sono:
Diversamente dall'SMTP, per ricevere la posta ha bisogno dell'autenticazione con username e pass. Si possono listare i messaggi, che vengono identificati con un numero, e poi cancellati dal server, e non posso più rileggere i messaggi se accedo a un altro client.
IMAP invece mantiene tutti i messaggi sul server e si può accedervi da diversi client. I messaggi in genere contengono più oggetti, esempio testo e allegati. Il MIME è quello che me li fa vedere. Devo anche stabilire un marcatore per dividere un tipo di oggetto da un altro, eg. BOUNDARY: "--next part 011397--", quindi dopo questa riga so che c'è un altro oggetto di diverso.
Poi, nel DATA di una mail, ogni singolo pezzo ha il suo charnet e il suo tipo MIME.
Domain Name System: è basato su architetture client - server ma è un protocollo "fondativo" di internet, un servizo offerto alle applicazioni.
I servizi offerti sono:
Perchè non è una buona idea avere un registro centrale? Perchè:
Il DNS usa un database distribuito, strutturato con server organizzati gerarchicamente: in pratica se non so una cosa il DNS sa a quale altro server chiedere, magari di livello superiore. Usa inoltre una cache per mantenere la lista dei nomi.
Nella gerarchia c'è un ROOT DNS (ce ne sono pochi nel mondo) e poi altri livelli più bassi, uno per il dominio (.com, .edu, ecc.. => server top level) e infine quelli locali.
Nelle organizzazioni si possono mantenere DNS per indirizzi interni alla rete.
I DNS mantengono una cache (aggiornata) di indirizzi dopo che ne hanno trovati alcuni sconosciuti.
Al DNS si possono fare delle richieste:
Il formato delle richieste RR (Resource Record) sono del tipo: name, value, type, TTL e anche le risposte sono così. A seconda del tipo di chiamata il VALUE contiene cose diverse.
Le QUERY e le REPLY hanno lo stesso formato di messaggio. A una richiesta DNS possono rispondere sia con DNS che hanno in cache, sia con quelli che sono AUTORITHATIVE per quel server. Se indico RECURSION voglio raggiungere il server autoritativo di quell'indirizzo, se no lascio decidere al DNS a cui chiedo.
Viaggiando dal sorgente al destinatario il pacchetto può essere soggetto a differenti ritardi. Elementi di ritardo possono essere:
Le strategie per ridurre il ritardo sono chiamate di Content Distribution. Tutte agiscono sul tempo di trasmissione aumentando e diminuendo l’uso della banda. Esse sono:
Server proxy: le richieste del client non vanno al server di origine ma si fermano in un server diverso che ha già in sè la maggioranza delle informazioni richieste dal client. Il vantaggio principale è derivato dal fatto che di solito la banda passante tra client e proxy è maggiore di quella tra client e server di origine. Inoltre riduce il tempo di risposta alla richiesta e il traffico al link. E' un'architettura con grande replicazione cache e a chi ha banda bassa può fornire risorse con banda alta richiedendo direttamente alla cache. Siccome non so come mettere i suoi disegni guardare le sue dispense:
Vedi slide 74-78 Ceravolo
Sono compagnie che affittano spazi dove i clienti possono replicare contenuti. Il cliente sviluppa un meccanismo che risolve le richieste del server centrale e le reindirizza al più vicino CND, quindi fornisco degli spazi dove smistare le richieste a vari mirroring. L’impatto positivo è la valorizzazione economica del servizio. Conoscere la mappa della rete è quindi importante.
Non si usa un’architettura client-server (richiesta a un fornitore di servizio) ma host che fungono sia da client che da server. Distribuire i contenuti non significa però diminuirli.
Ci sono tre tipi di file sharing:
Penso che tutti sappiano come sia il file sharing, i punti principali sono spiegati nella slide 81 di Ceravolo comunque.
In quest'architettura centralizzata il server riconosce l'host e lo registra e si occupa del lookup cioè controlla chi è l'host che può soddisfare la richiesta inviata da un altro host. (Lookup = richiesta di dati ai vicini, che propagano la richiesta ad altri vicini e man mano si allarga il giro)
I problemi di questo tipo sono:
Successivo a Napster. In questo caso le richieste di dati vengono propagate attraverso query attraverso una connessione TCP tra host. Le query sono gestite attraverso un TTL per cui dopo un po' non può più essere propagata la richiesta per non saturare la rete. Il protocollo ha una sua tipologia che si inserisce su internet.
Per capire meglio l'architettura vedi slide 86
In quest'architettura c'è un super peer cioè un gruppo leader che funge da server, collegati ciascuno ad altrettanti host tutti attraverso il protocollo TCP.
Ogni file ha un suo codice e una descrizione. Il client manda la query con la parola chiave al suo gruppo leader. Questo risponde con le informazioni richieste fornendo metadata (dati relativi al dato dato), hash e IP address. Se il gruppo leader deve inviare la domanda ad altri gruppi anche questi dovranno rispondere con le stesse informazioni. Infine il client sceglie i file da scaricare.
Ci sono dei problemi sull'efficienza e la sicurezza perchè un peer può ingannare l'altro modificando i dati visibili del file da scaricare. Limitato inoltre il download parallelo per via delle code nella rete.
La scalabilità di un protocollo è relativa all'efficacia del servizio di lookup (cioè quello che manda i messaggi di richiesta dei dati).
Due sono gli obiettivi principali:
Il progetto Chord si prefigge di sviluppare sistemi distribuiti scalabili (può allargare la sua distribuzione) e robusti sfruttando le idee del peer-to-peer. Il componente base del progetto Chord è l'algoritmo di ricerca distribuita basata su tabelle di hash, tabelle di codici di dati. Chord può trovare dati usando log(N) messaggi, dove N è il numero di nodi nel sistema. Perciò per trovare dei dati non fa passare il messaggio di richiesta da tutti i nodi ma solo a logN nodi attraverso un sistema di ricerca del "vicino". Cioè invio la richiesta a un nodo conoscendo già il suo o i suoi vicini.
Cos'è un socket? Un socket in inglese è letteralmente la "presa da muro". Attraverso di esso un processo applicativo può sia mandare che ricevere messaggi da un altro processo. I socket permettono al protocollo applicativo di comunicare con il protocollo di trasporto. Il protocollo di trasporto può essere come tutti ben sappiamo UDP o TCP.
TCP è un protocollo affidabile, ossia trasferisce pacchetti in ordine tra client e server. E' più lungo da utilizzare perchè bisogna tener conto del fatto che il client e il server "si mettono d'accordo" su dettagli di trasferimento.
Infatti il client contatta il server che deve essere prima fatto "partire" (running) e deve essere stata creata una socket door che riceve il client.
Quando il client vuole contattare il server deve fornire IP address e port number. Quando il client crea il socket il client TCP stabilisce una connessione con il server TCP. E ogni volta che il client lo contatta il server TCP crea nuovi socket per il processo per comunicare con il client. Il server può parlare con molti client e identificarli attraverso il numero di porta.
Stream jargon (non ho la minima idea del perchè sia messo qui, ma teniamolo)
Lo stream è una sequenza di caratteri che scorre dentro o fuori dal processo.
Esempio client/server with TCP
1. client legge le righe che riceve in input (inFromUser stream) e le manda al server via socket (outToServer stream)
2. il server legge le linee dal socket
3. le converte in maiuscolo (uppercase???)e le rimanda al client
4. il client legge, stampa e modifica le linee dal socket (inFromServer stream)
vedi slide 100-104 per un esempio di Java client/server TCP
UDP non dà connessione e il lavoro è perciò ridotto perchè non c'è bisogno dei patteggiamenti (le "strette di mano") da fare con UDP, è un modello più semplice perchè non c'è bisogno di aprire la connessione. Però come ricordiamo è un protocollo non affidabile quindi i pacchetti possono essere persi o ricevuti in ordine sbagliato. Che differenza c'è? C'è che l'IP address e la porta di destinazione del mittente deve essere estratta direttamente dal pacchetto inviato, non viene mandato a parte.
vedi slide 107-112 per un esempio di Java client/server UDP
(nb. può servirci per costruire quello da fare per Sassi?)
Un web server si occupa di richieste HTTP e di tutti gli annessi e i connessi, cioè: accettare le richieste, analizzare l'header, ottenere le richieste dal server file system, creare una risposta al messaggio HTTP (header lines + file), mandare la risposta al client.
Dopo aver creato un server HTTP posso fare le richieste direttamente dal browser.
Torna alla pagina di Sistemi per l'elaborazione delle informazioni