cerca
Temi d'esame di Sistemi - 9/9/2005
modifica cronologia stampa login logout

Wiki

UniCrema


Materie per semestre

Materie per anno

Materie per laurea


Help

Uni.TemiEsameSED07 History

Hide minor edits - Show changes to output

Changed line 185 from:
''GET'' www.dti.unimi.it/default.htm HTTP/1.0\\
to:
''GET'' /default.htm HTTP/1.0\\
Changed line 190 from:
''GET'' /default.htm HTTP/1.1\\
to:
''GET'' / HTTP/1.1\\
Changed line 233 from:
[[Torna alla pagina di Sistemi Anticoncezionali delle Reti e dei Damiani->Sistemi]]
to:
[[Torna alla pagina di Sistemi per l'elaborazione delle informazioni->Sistemi]]
Changed line 2 from:
[[Torna alla pagina di Sistemi Anticoncezionali delle Reti e dei Damiani->Sistemi]]
to:
[[Torna alla pagina di Sistemi per l'elaborazione delle informazioni->Sistemi]]
Changed line 186 from:
''Host'': dti.unimi.it\\
to:
''Host'': www.dti.unimi.it\\
Changed lines 198-199 from:
'''Un sito Web di grande successo offre la registrazione degli utenti alla URL http://ebusiness.com/register.htm. Poichè la procedura consiste di 3 form da compilare una dopo l’altra, si vuol permettere all’utente di abbandonare la procedura di registrazione in ogni momento per riprendere quando lo desidera. Per evitare di sprecare risorse sul server, si desidera memorizzare lato server le sole registrazioni complete. Illustrate una tecnica vostra scelta per risolvere il problema.'''
to:
'''Un sito Web di grande successo offre la registrazione degli utenti alla URL http://ebusiness.com/register.htm. Poichè la procedura consiste di 3 form da compilare una dopo l’altra, si vuol permettere all’utente di abbandonare la procedura di registrazione in ogni momento per riprendere quando lo desidera. Per evitare di sprecare risorse sul server, si desidera memorizzare lato server le sole registrazioni complete. Illustrate una tecnica a vostra scelta per risolvere il problema.'''
Changed line 192 from:
''Range'': bytes 0-300\\
to:
''Range'': bytes=0-300\\
Changed line 161 from:
* 'gethostbyname'', è il nome del metodo remoto;
to:
* ''gethostbyname'', è il nome del metodo remoto;
Changed lines 81-82 from:
'''La più semplice API verso il DNS è quella fornita dalla socket library con le chiamate gethostbyname()e gethostbyaddr(). Spiegatene il significato e usatele per scrivere lo pseudocodice di un programma che fornisca la stessa funzionalità di query diretta del comando nslookup.'''
to:
'''La più semplice API verso il DNS è quella fornita dalla socket library con le chiamate gethostbyname() e gethostbyaddr(). Spiegatene il significato e usatele per scrivere lo pseudocodice di un programma che fornisca la stessa funzionalità di query diretta del comando nslookup.'''
Changed lines 85-90 from:
La chiamata gethostbyname() riceve una struttura con il nome DNS di un host e ne restituisce una sockaddr. La chiamata gethostbyaddr() fa l'esatto contrario.

Nslookup
(Name Server Lookup) è uno strumento presente in tutti i sistemi operativi che utilizzano il protocollo TCP/IP, e consente di effettuare delle query ad un server DNS per la risoluzione di indirizzi IP o Hostname. Posso in pratica ottenere da un dominio il relativo indirizzo IP o nome host e viceversa.

L'implementazione di nslookup che propongo legge un argomento (opzione) da linea di comando: se è "-d" chiama gethostbyaddr(), se è "-i" chiama gethostbyname(). (nslookup non ha bisogno in realtà di queste opzioni, dal momento che se gli do un nome mi restituisce l'ip e viceversa).
to:
Le ''API'' sono l'Interfaccia di Programmazione di un'Applicazione, ovvero un insieme di procedure disponibili al programmatore per svolgere un determinato compito. ''Nslookup'' (Name Server Lookup) è uno strumento presente in tutti i sistemi operativi che utilizzano il protocollo TCP/IP, e consente di effettuare delle query ad un server DNS per la risoluzione di indirizzi IP o Hostname. Posso in pratica ottenere da un dominio il relativo indirizzo IP o nome host e viceversa.

La chiamata ''gethostbyname''() riceve una struttura con il nome DNS di un host e ne restituisce una sockaddr. La chiamata ''gethostbyaddr''() fa l'esatto contrario.

L'implementazione di nslookup che propongo legge un argomento (opzione) da linea di comando: se è "-d" chiama gethostbyaddr(
), se è "-i" chiama gethostbyname().\\
Da notare che nslookup non ha bisogno in realtà di queste opzioni, dal momento che se gli do un nome mi restituisce l'ip e viceversa
.
Added lines 93-94:
[...]
Changed line 97 from:
if(argv[1] == "-d") // traduzione diretta: in realtà dovrei fare uno strcmp
to:
if(argv[1] == "-d") // per brevità gestisco le stringhe per assegnamento, senza "strcmp()"
Changed lines 143-148 from:
L'interfaccia è così implementata: ''(viene qui scritta anche se non era richiesta)''

[@interface { uiid 12345 ...
/* interfaccia in IDL per il DNS */
[out] int status gethostbyname
( [in] string nome, [in]ipaddress )
...
to:
Anche se non è richiesto, vediamo come potrebbe essere implementata l'interfaccia IDL.

[@
//
interface header IDL per il DNS
[ uiid 12345 ... //calcolato opportunamente
version(1.0)
]

// interface body
interface DNS {
[out] int status gethostbyname ( [in] string nome, [in] ipaddress
);
...
Changed lines 158-163 from:
# Uso rpcgen su idl e ottengo stub.o e skeleton.o
# link stub.o con client.o dove client è qualunque programma che chiamava la gethostbyname ( ottengo clientrpc.exe)
# link di skeleton.o con server.o ( oggetto sulla socket library remota ) ottenuto dalla socjet library su macchina server
, ottengo serverrpc.exe
# registro l'interfaccia con portmapper; lancio server ( serve perché così chi chiama trova la porta giusta )
# uso clientrpc
.exe al posto del vecchio client.exe
to:
Analizziamo come è stato descritto il metodo remoto gethostbyname:
* ''[out]'', indica che il valore di ritorno del metodo deve essere restituito dal server al client;
* ''int status'', specifica nome e tipo del valore di ritorno del metodo;
* 'gethostbyname'', è il nome del metodo remoto;
* ''[in]''
, indica che il parametro seguente è passato dal client al server;
* ''string nome'', indica nome e tipo del parametro passato
.

A questo punto compilo con ''rpcgen'' o ''IDL-compiler'' l'IDL appena creata, ottenendo tre file:
* ''DNS
.h'' (o DNS_h.h), che è l'header file da includere sia nel client che nel server, che contiene le definizioni dei metodi remoti;
* ''DNS_c.c'', ovvero lo stub che gestisce la comunicazione con il server, da linkare al client;
* ''DNS_s.c'', ovvero lo skeleton che gestisce la comunicazione con il client, da linkare al server.

Linkando client e server coi rispettivi stub e skeleton e compilando, ottengo due nuovi eseguibili che chiamerò clientrpc.
exe e serverrpc.exe. Non mi resta che:
# registrare l'interfaccia col portmapper del server (porta 111) in modo che il chiamante si connetta alla porta giusta, e lanciare serverrpc.exe .
# lanciare clientrpc.exe al posto del vecchio client.exe .
Changed lines 8-9 from:
'''Un server TCP a connessione multipla è stato usando con la socket library come segue:'''
to:
'''Un server TCP a connessione multipla è stato realizzato usando la socket library come segue:'''
Changed lines 34-36 from:
//il 3° NULL è perchè dò per scontato che non ci siano richieste in attesa
// è una chiamata bloccante: rileva solo la presenza dei dati sul primo socket pronto
to:
Changed lines 36-38 from:
to:
//per capire quali socket hanno richiesto l'accesso scorro l'array di sockset
//e si applica fd_isset, che restituisce un valore non zero se il socket è stato marcato
Changed lines 40-41 from:
handleTCPservice(socket[i]); //se sì, chiama la funzione richiesta
to:
handleTCPservice(socket[i]); //...se sì, chiama la funzione richiesta
Changed lines 45-48 from:
Da notare che se con la accept avevo un unico socket attivo, con la select ne avrò più di uno contemporaneamente. Inoltre, se la accept garantiva la simultaneità grazie alla fork (più client serviti alla volta), con la select ho invece un unico processo in esecuzione (che può dunque servire un solo handleTCP per volta).

Tuttavia, nulla mi impedisce di utilizzare una fork anche nella select. In questo modo avrei sì la simultaneità, ma non è poi così indispensabile dato che usiamo la select quando ci sono pochi socket da gestire. Può avere un senso solo quando
il tempo di servizio è alto, così invece di dover eseguire più volte lo stesso servizio (facendo aspettare gli altri client) lo smisto su processi diversi simultaneamente.
to:
Commenti al codice:
* ''select'':
** il primo parametro, pur essendo definito come il numero di descrittori da esaminare, è posto a 0 perché nelle Winsock viene ignorato;
** l'ultimo NULL passato come parametro è relativo al timeout, ed è così settato perché do per scontato che non ci siano richieste in attesa;
** è una chiamata bloccante, in quanto rileva solo la presenza dei dati sul primo socket pronto;
** evito il controllo sulla corretta esecuzione della select, dando per scontato che qualcuno effettui una connessione su uno dei socket del sockset);
* ''FD_ISSET'', restituisce un valore non zero se
il socket esaminato è stato marcato. Quindi permette di capire quali socket hanno richiesto di essere serviti;
* ''handleTCPservice''() è una pseudo-funzione che si applica a un qualsiasi servizio richiesto dal client.

Da notare che se con la accept avevo un unico socket attivo, con la select ne avrò più di uno contemporaneamente. Inoltre, se la accept garantiva la simultaneità grazie alla fork (più client serviti alla volta), con la select ho invece un unico processo in esecuzione (che può dunque servire un solo handleTCPservice per volta).

Tuttavia, nulla mi impedisce di utilizzare una fork anche nella select. In questo modo avrei sì la simultaneità, ma non è poi così indispensabile dato che usiamo la select quando ci sono pochi socket da gestire. Può avere un senso '''solo quando il tempo di servizio è alto'''
, così invece di dover eseguire più volte lo stesso servizio (facendo aspettare gli altri client) lo smisto su processi diversi simultaneamente.
Changed lines 64-65 from:
//il 3° NULL è perchè dò per scontato che non ci siano richieste in attesa
to:
Changed lines 67-68 from:
for(i=0; i<=2; i++)
if(FD_ISSET (sockset[i], &sockset)) //se c'è almeno un socket pronto...
to:
for(i=0; i<=2; i++) //scandisco i tre socket e...
if(FD_ISSET (sockset[i], &sockset)) //...se c'è almeno un socket pronto...
Changed lines 83-84 from:
[@String *nome, *ipaddress; // per comodità non li gestisco come struct ma come string
to:
[@
String *nome, *ipaddress; // per comodità non li gestisco come struct ma come string
Changed lines 89-90 from:
// Voglio ora ottenere il nome dall'indirizzo IP passato,
to:
// Voglio ora ottenere il nome dall'indirizzo IP passato,
Changed lines 97-98 from:
//...nel caso non esista corrispondenza, il programma esce visualizzando l'errore
to:
//...nel caso non esista corrispondenza,
//il programma esce visualizzando l'errore
Changed lines 112-113 from:
nome = argv[2]; // memorizzo il nome passato da linea di comando.In questa opzione
to:
nome = argv[2]; // memorizzo il nome passato da linea di comando
Changed line 118 from:
//anche in questo caso vale lo stesso discorso delle corrispondenze fatto prima
to:
//anche in questo caso vale il discorso delle corrispondenze fatto prima
Changed lines 83-90 from:

L'interfaccia è così implementata: ''(viene qui scritta anche se non era richiesta)''

[@interface { uiid 12345 ...
/* interfaccia in IDL per il DNS */
[out] int status gethostbyname (
[in] string nome, [in]ipaddress )
...
to:
[@String *nome, *ipaddress; // per comodità non li gestisco come struct ma come string

if(argv[1] == "-d")
// traduzione diretta: in realtà dovrei fare uno strcmp
{
ipaddress = argv
[2]; // memorizzo l'ipaddress passato da linea di comando

// Voglio ora ottenere il nome dall'indirizzo IP passato,
// che andrà poi convertito nel tipo di rete opportuno

if(!(status = gethostbyaddr(nome, ipaddress
))
//gli passo sia il nome che l'indirizzo perché durante l'interrogazione al DNS
//devo verificare che esista un'effettiva corrispondenza tra indirizzo e nome
{
//
...nel caso non esista corrispondenza, il programma esce visualizzando l'errore
perror("Resolver non presente");
exit(-1);
}
else
{
//...se invece esiste corrispondenza, stampa a video il nome
printf("%s", nome);
exit(0);
}
Added lines 107-127:

else if(argv[1] == "-i")
{
nome = argv[2]; // memorizzo il nome passato da linea di comando.In questa opzione

// Voglio ora ottenere l'indirizzo IP dal nome passato,
// che andrà poi convertito nel tipo di rete opportuno

if(!(status = gethostbyname(nome, ipaddress))
//anche in questo caso vale lo stesso discorso delle corrispondenze fatto prima
{
perror("Resolver non presente");
exit(-1);
}
else
{
//...se invece esiste corrispondenza, stampa a video l'indirizzo IP
printf("%s", ipaddress);
exit(0);
}
}
Added lines 130-138:
L'interfaccia è così implementata: ''(viene qui scritta anche se non era richiesta)''

[@interface { uiid 12345 ...
/* interfaccia in IDL per il DNS */
[out] int status gethostbyname ( [in] string nome, [in]ipaddress )
...
}
@]
Changed lines 83-106 from:
[@
String *nome, *ipaddress; // per comodità non li gestisco come struct ma come string

if(argv[1] == "-d")
// traduzione diretta: in realtà dovrei fare uno strcmp
{
ipaddress = argv
[2]; // memorizzo l'ipaddress passato da linea di comando

// Voglio ora ottenere il nome dall'indirizzo IP passato,
// che andrà poi convertito nel tipo di rete opportuno

if(!(status = gethostbyaddr(nome, ipaddress
))
//gli passo sia il nome che l'indirizzo perché durante l'interrogazione al DNS
//devo verificare che esista un'effettiva corrispondenza tra indirizzo e nome
{
//
...nel caso non esista corrispondenza, il programma esce visualizzando l'errore
perror("Resolver non presente");
exit(-1);
}
else
{
//...se invece esiste corrispondenza, stampa a video il nome
printf("%s", nome);
exit(0);
}
to:

L'interfaccia è così implementata: ''(viene qui scritta anche se non era richiesta)''

[@interface { uiid 12345 ...
/* interfaccia in IDL per il DNS */
[out] int status gethostbyname (
[in] string nome, [in]ipaddress )
...
Deleted lines 91-111:

else if(argv[1] == "-i")
{
nome = argv[2]; // memorizzo il nome passato da linea di comando.In questa opzione

// Voglio ora ottenere l'indirizzo IP dal nome passato,
// che andrà poi convertito nel tipo di rete opportuno

if(!(status = gethostbyname(nome, ipaddress))
//anche in questo caso vale lo stesso discorso delle corrispondenze fatto prima
{
perror("Resolver non presente");
exit(-1);
}
else
{
//...se invece esiste corrispondenza, stampa a video l'indirizzo IP
printf("%s", ipaddress);
exit(0);
}
}
Deleted lines 93-101:
L'interfaccia è così implementata: ''(viene qui scritta anche se non era richiesta)''

[@interface { uiid 12345 ...
/* interfaccia in IDL per il DNS */
[out] int status gethostbyname ( [in] string nome, [in]ipaddress )
...
}
@]
Added lines 150-205:
!!Esercizio 3
'''Scrivete una richiesta HTTP/1.0 per la pagina default.htm sul server www.dti.unimi.it\\
Scrivete una richiesta sul server www.dti.unimi.it per la URL radice /, ma soltanto i byte da 0 a 300.'''

%red%[-'''SOLUZIONE'''-]

'''prima richiesta:'''\\
''GET'' www.dti.unimi.it/default.htm HTTP/1.0\\
''Host'': dti.unimi.it\\
''Connection'': close\\\

'''seconda richiesta:'''\\
''GET'' /default.htm HTTP/1.1\\
''Host'': www.dti.unimi.it\\
''Range'': bytes 0-300\\
''Connection'': close\\\

----

!!Esercizio 4
'''Un sito Web di grande successo offre la registrazione degli utenti alla URL http://ebusiness.com/register.htm. Poichè la procedura consiste di 3 form da compilare una dopo l’altra, si vuol permettere all’utente di abbandonare la procedura di registrazione in ogni momento per riprendere quando lo desidera. Per evitare di sprecare risorse sul server, si desidera memorizzare lato server le sole registrazioni complete. Illustrate una tecnica vostra scelta per risolvere il problema.'''

%red%[-'''SOLUZIONE'''-]

Una tecnica per risolvere questo problema è quella dei cookie. I cookie sono file testuali contenenti attributi per simulare lo stato di una sessione HTTP. Possono servire per: informazioni generali (pagine visitate, prodotti cercati, preferenze, ecc / autenticazione senza ripetere il login.\\
Immaginiamo che in fondo alla pagina dopo i 3 form ci sarà un tasto di ''invio'', quindi se l'utente compila tutte e tre le form le informazioni vengono inviate e salvate sul server.\\
Mentre se l'utente compila solo parzialmente i form sul server non viene salvato nulla, ma vengono utilizzati i cookie che conterranno le informazioni parziali inserite dall'utente. La prossima volta che l'utente accederà alla pagina il client controllerà la presenza dei cookie, se li rileva inserisce le informazioni nei vari campi compilati precedentemente.\\\

----

!!Domande:
# '''Se una pagina Web contiene 10 tag <img ...> quante connessioni TCP verranno aperte con http1.0 quando si accede alla pagina? quante con http 1.1?'''
# '''Spiegare la differenza tra i protocolli POP e IMAP'''
# '''Cos'è IIOP e che ruolo ha nel protocollo CORBA?'''

%red%[-'''SOLUZIONE'''-]

'''1.'''\\
In HTTP/1.0 ogni immagine o altro file è caricato come connessione differente. Quindi avrò 10 connessioni per ogni mmagine più una per la pagina richiesta, quindi 11 totali.\\
Invece in HTTP/1.1 viene fatto un ''multiple-get'' nella stessa connessione. Quindi avrò un unica connessione.\\
{+ ''NOTA HTTP:'' +} se faccio connessioni web corte ( HTTP/1.0 ) non do il tempo di arrivare ad una dimensione ottimale della finestra, mentre con HTTP/1.1 arrivo prima ad una finestra ottimale TCP di connessione.\\
Infatti minore è la dimensione delle immagini, minore è la differenza tra HTTP/1.0 e HTTP/1.1. Se sono "grosse" fa differenza perché passo più tempo al livello ottimale della finestra.\\\

'''2.'''\\
Il protocollo IMAP ( Internet Messagge Access Protocol ) è un’alternativa a POP3.\\
Come POP3 definisce un’astrazione nota come casella postale, posta sul computer server. L’utente attiva un client IMAP che contatta il server per recuperare i messaggi.\\
La '''diversità''' tra i due protocolli sta nel fatto che IMAP permette di creare, cancellare o rinominare dinamicamente le caselle postali. IMAP fornisce inoltre una funzionalità estesa per il recupero e l’elaborazione dei messaggi. L’utente può ottenere informazioni su un messaggio o esaminare i campi dell’intestazione senza recuperare l’intero messaggio; inoltre, può cercare una stringa specificata e riprendere parti specifiche di un messaggio.\\
''(dal libro)''\\\

'''3.'''\\
IIOP ( Internet Inter-ORB Protocol ) è un programma basato su CORBA ed è una particolare implementazione del protocollo GIOP che si avvale del protocollo TCP/IP per la realizzazione dello strato di trasporto dei messaggi tra oggetti remoti.\\
{+ ''NOTA:'' +} Non mi pare che abbia mai fatto questa parte (o magari mentre la faceva stavo giocando a Quake :p). Però a %newwin%[[http://www.mokabyte.it/1998/12/iiop.htm | questo]] link trovate qualche spiegazione interessante sul protocollo GIOP e IIOP.

----

[[Torna alla pagina di Sistemi Anticoncezionali delle Reti e dei Damiani->Sistemi]]
Added lines 72-149:
!!Esercizio 2
'''La più semplice API verso il DNS è quella fornita dalla socket library con le chiamate gethostbyname()e gethostbyaddr(). Spiegatene il significato e usatele per scrivere lo pseudocodice di un programma che fornisca la stessa funzionalità di query diretta del comando nslookup.'''

%red%[-'''SOLUZIONE'''-]

La chiamata gethostbyname() riceve una struttura con il nome DNS di un host e ne restituisce una sockaddr. La chiamata gethostbyaddr() fa l'esatto contrario.

Nslookup (Name Server Lookup) è uno strumento presente in tutti i sistemi operativi che utilizzano il protocollo TCP/IP, e consente di effettuare delle query ad un server DNS per la risoluzione di indirizzi IP o Hostname. Posso in pratica ottenere da un dominio il relativo indirizzo IP o nome host e viceversa.

L'implementazione di nslookup che propongo legge un argomento (opzione) da linea di comando: se è "-d" chiama gethostbyaddr(), se è "-i" chiama gethostbyname(). (nslookup non ha bisogno in realtà di queste opzioni, dal momento che se gli do un nome mi restituisce l'ip e viceversa).

[@
String *nome, *ipaddress; // per comodità non li gestisco come struct ma come string

if(argv[1] == "-d") // traduzione diretta: in realtà dovrei fare uno strcmp
{
ipaddress = argv[2]; // memorizzo l'ipaddress passato da linea di comando

// Voglio ora ottenere il nome dall'indirizzo IP passato,
// che andrà poi convertito nel tipo di rete opportuno

if(!(status = gethostbyaddr(nome, ipaddress))
//gli passo sia il nome che l'indirizzo perché durante l'interrogazione al DNS
//devo verificare che esista un'effettiva corrispondenza tra indirizzo e nome
{
//...nel caso non esista corrispondenza, il programma esce visualizzando l'errore
perror("Resolver non presente");
exit(-1);
}
else
{
//...se invece esiste corrispondenza, stampa a video il nome
printf("%s", nome);
exit(0);
}
}

else if(argv[1] == "-i")
{
nome = argv[2]; // memorizzo il nome passato da linea di comando.In questa opzione

// Voglio ora ottenere l'indirizzo IP dal nome passato,
// che andrà poi convertito nel tipo di rete opportuno

if(!(status = gethostbyname(nome, ipaddress))
//anche in questo caso vale lo stesso discorso delle corrispondenze fatto prima
{
perror("Resolver non presente");
exit(-1);
}
else
{
//...se invece esiste corrispondenza, stampa a video l'indirizzo IP
printf("%s", ipaddress);
exit(0);
}
}
@]

L'interfaccia è così implementata: ''(viene qui scritta anche se non era richiesta)''

[@interface { uiid 12345 ...
/* interfaccia in IDL per il DNS */
[out] int status gethostbyname ( [in] string nome, [in]ipaddress )
...
}
@]

# Uso rpcgen su idl e ottengo stub.o e skeleton.o
# link stub.o con client.o dove client è qualunque programma che chiamava la gethostbyname ( ottengo clientrpc.exe)
# link di skeleton.o con server.o ( oggetto sulla socket library remota ) ottenuto dalla socjet library su macchina server, ottengo serverrpc.exe
# registro l'interfaccia con portmapper; lancio server ( serve perché così chi chiama trova la porta giusta )
# uso clientrpc.exe al posto del vecchio client.exe

Scopriamo runtime un interfaccia nota, è una chiamata {+ statica +}. C'è una identificazione runtime delle porte dell'interfaccia.\\\

----
Deleted lines 71-204:
!!Esercizio 2
'''La più semplice API verso il DNS è quella fornita dalla socket library con le chiamate gethostbyname()e gethostbyaddr(). Spiegatene il significato e usatele per scrivere lo pseudocodice di un programma che fornisca la stessa funzionalità di query diretta del comando nslookup.'''

%red%[-'''SOLUZIONE'''-]

La chiamata gethostbyname() riceve una struttura con il nome DNS di un host e ne restituisce una sockaddr. La chiamata gethostbyaddr() fa l'esatto contrario.

Nslookup (Name Server Lookup) è uno strumento presente in tutti i sistemi operativi che utilizzano il protocollo TCP/IP, e consente di effettuare delle query ad un server DNS per la risoluzione di indirizzi IP o Hostname. Posso in pratica ottenere da un dominio il relativo indirizzo IP o nome host e viceversa.

L'implementazione di nslookup che propongo legge un argomento (opzione) da linea di comando: se è "-d" chiama gethostbyaddr(), se è "-i" chiama gethostbyname(). (nslookup non ha bisogno in realtà di queste opzioni, dal momento che se gli do un nome mi restituisce l'ip e viceversa).

[@
String *nome, *ipaddress; // per comodità non li gestisco come struct ma come string

if(argv[1] == "-d") // traduzione diretta: in realtà dovrei fare uno strcmp
{
ipaddress = argv[2]; // memorizzo l'ipaddress passato da linea di comando

// Voglio ora ottenere il nome dall'indirizzo IP passato,
// che andrà poi convertito nel tipo di rete opportuno

if(!(status = gethostbyaddr(nome, ipaddress))
//gli passo sia il nome che l'indirizzo perché durante l'interrogazione al DNS
//devo verificare che esista un'effettiva corrispondenza tra indirizzo e nome
{
//...nel caso non esista corrispondenza, il programma esce visualizzando l'errore
perror("Resolver non presente");
exit(-1);
}
else
{
//...se invece esiste corrispondenza, stampa a video il nome
printf("%s", nome);
exit(0);
}
}

else if(argv[1] == "-i")
{
nome = argv[2]; // memorizzo il nome passato da linea di comando.In questa opzione

// Voglio ora ottenere l'indirizzo IP dal nome passato,
// che andrà poi convertito nel tipo di rete opportuno

if(!(status = gethostbyname(nome, ipaddress))
//anche in questo caso vale lo stesso discorso delle corrispondenze fatto prima
{
perror("Resolver non presente");
exit(-1);
}
else
{
//...se invece esiste corrispondenza, stampa a video l'indirizzo IP
printf("%s", ipaddress);
exit(0);
}
}
@]

L'interfaccia è così implementata: ''(viene qui scritta anche se non era richiesta)''

[@interface { uiid 12345 ...
/* interfaccia in IDL per il DNS */
[out] int status gethostbyname ( [in] string nome, [in]ipaddress )
...
}
@]

# Uso rpcgen su idl e ottengo stub.o e skeleton.o
# link stub.o con client.o dove client è qualunque programma che chiamava la gethostbyname ( ottengo clientrpc.exe)
# link di skeleton.o con server.o ( oggetto sulla socket library remota ) ottenuto dalla socjet library su macchina server, ottengo serverrpc.exe
# registro l'interfaccia con portmapper; lancio server ( serve perché così chi chiama trova la porta giusta )
# uso clientrpc.exe al posto del vecchio client.exe

Scopriamo runtime un interfaccia nota, è una chiamata {+ statica +}. C'è una identificazione runtime delle porte dell'interfaccia.\\\

----

!!Esercizio 3
'''Scrivete una richiesta HTTP/1.0 per la pagina default.htm sul server www.dti.unimi.it\\
Scrivete una richiesta sul server www.dti.unimi.it per la URL radice /, ma soltanto i byte da 0 a 300.'''

%red%[-'''SOLUZIONE'''-]

'''prima richiesta:'''\\
''GET'' www.dti.unimi.it/default.htm HTTP/1.0\\
''Host'': dti.unimi.it\\
''Connection'': close\\\

'''seconda richiesta:'''\\
''GET'' /default.htm HTTP/1.1\\
''Host'': www.dti.unimi.it\\
''Range'': bytes 0-300\\
''Connection'': close\\\

----

!!Esercizio 4
'''Un sito Web di grande successo offre la registrazione degli utenti alla URL http://ebusiness.com/register.htm. Poichè la procedura consiste di 3 form da compilare una dopo l’altra, si vuol permettere all’utente di abbandonare la procedura di registrazione in ogni momento per riprendere quando lo desidera. Per evitare di sprecare risorse sul server, si desidera memorizzare lato server le sole registrazioni complete. Illustrate una tecnica vostra scelta per risolvere il problema.'''

%red%[-'''SOLUZIONE'''-]

Una tecnica per risolvere questo problema è quella dei cookie. I cookie sono file testuali contenenti attributi per simulare lo stato di una sessione HTTP. Possono servire per: informazioni generali (pagine visitate, prodotti cercati, preferenze, ecc / autenticazione senza ripetere il login.\\
Immaginiamo che in fondo alla pagina dopo i 3 form ci sarà un tasto di ''invio'', quindi se l'utente compila tutte e tre le form le informazioni vengono inviate e salvate sul server.\\
Mentre se l'utente compila solo parzialmente i form sul server non viene salvato nulla, ma vengono utilizzati i cookie che conterranno le informazioni parziali inserite dall'utente. La prossima volta che l'utente accederà alla pagina il client controllerà la presenza dei cookie, se li rileva inserisce le informazioni nei vari campi compilati precedentemente.\\\

----

!!Domande:
# '''Se una pagina Web contiene 10 tag <img ...> quante connessioni TCP verranno aperte con http1.0 quando si accede alla pagina? quante con http 1.1?'''
# '''Spiegare la differenza tra i protocolli POP e IMAP'''
# '''Cos'è IIOP e che ruolo ha nel protocollo CORBA?'''

%red%[-'''SOLUZIONE'''-]

'''1.'''\\
In HTTP/1.0 ogni immagine o altro file è caricato come connessione differente. Quindi avrò 10 connessioni per ogni mmagine più una per la pagina richiesta, quindi 11 totali.\\
Invece in HTTP/1.1 viene fatto un ''multiple-get'' nella stessa connessione. Quindi avrò un unica connessione.\\
{+ ''NOTA HTTP:'' +} se faccio connessioni web corte ( HTTP/1.0 ) non do il tempo di arrivare ad una dimensione ottimale della finestra, mentre con HTTP/1.1 arrivo prima ad una finestra ottimale TCP di connessione.\\
Infatti minore è la dimensione delle immagini, minore è la differenza tra HTTP/1.0 e HTTP/1.1. Se sono "grosse" fa differenza perché passo più tempo al livello ottimale della finestra.\\\

'''2.'''\\
Il protocollo IMAP ( Internet Messagge Access Protocol ) è un’alternativa a POP3.\\
Come POP3 definisce un’astrazione nota come casella postale, posta sul computer server. L’utente attiva un client IMAP che contatta il server per recuperare i messaggi.\\
La '''diversità''' tra i due protocolli sta nel fatto che IMAP permette di creare, cancellare o rinominare dinamicamente le caselle postali. IMAP fornisce inoltre una funzionalità estesa per il recupero e l’elaborazione dei messaggi. L’utente può ottenere informazioni su un messaggio o esaminare i campi dell’intestazione senza recuperare l’intero messaggio; inoltre, può cercare una stringa specificata e riprendere parti specifiche di un messaggio.\\
''(dal libro)''\\\

'''3.'''\\
IIOP ( Internet Inter-ORB Protocol ) è un programma basato su CORBA ed è una particolare implementazione del protocollo GIOP che si avvale del protocollo TCP/IP per la realizzazione dello strato di trasporto dei messaggi tra oggetti remoti.\\
{+ ''NOTA:'' +} Non mi pare che abbia mai fatto questa parte (o magari mentre la faceva stavo giocando a Quake :p). Però a %newwin%[[http://www.mokabyte.it/1998/12/iiop.htm | questo]] link trovate qualche spiegazione interessante sul protocollo GIOP e IIOP.

----

[[Torna alla pagina di Sistemi Anticoncezionali delle Reti e dei Damiani->Sistemi]]
Changed lines 129-130 from:
to:
@]
Changed line 133 from:
interface { uiid 12345 ...
to:
[@interface { uiid 12345 ...
Changed lines 146-147 from:
* Scopriamo runtime un interfaccia nota, è una chiamata {+ statica +}. C'è una identificazione runtime delle porte dell'interfaccia.\\\
to:
Scopriamo runtime un interfaccia nota, è una chiamata {+ statica +}. C'è una identificazione runtime delle porte dell'interfaccia.\\\
Changed lines 33-34 from:
status = select (0, &sockset, NULL, NULL, NULL);//il 3° NULL è perchè dò per scontato che non ci siano richieste
//
in attesa
to:
status = select (0, &sockset, NULL, NULL, NULL);
//il 3° NULL è perchè dò per scontato che non ci siano richieste in attesa
Changed lines 54-56 from:
status = select (0, &sockset, NULL, NULL, NULL);//il 3° NULL è perchè dò per scontato che non ci siano richieste
//
in attesa
to:
status = select (0, &sockset, NULL, NULL, NULL);
//il 3° NULL è perchè dò per scontato che non ci siano richieste in attesa
Added lines 79-80:
Nslookup (Name Server Lookup) è uno strumento presente in tutti i sistemi operativi che utilizzano il protocollo TCP/IP, e consente di effettuare delle query ad un server DNS per la risoluzione di indirizzi IP o Hostname. Posso in pratica ottenere da un dominio il relativo indirizzo IP o nome host e viceversa.
Changed lines 88-92 from:
ipaddress = argv[2]; // memorizzo l'ipaddress passato da linea di comando. Nell'opzione
// voglio andare dall'indirizzo IP al nome
// andrà poi convertito nel tipo di rete opportuno

if(!(status = gethostbyaddr(nome, ipaddress))//ne chiama 2 perchè controlla che si sia l'ind corrispondente
to:
ipaddress = argv[2]; // memorizzo l'ipaddress passato da linea di comando

// Voglio ora ottenere il nome dall'indirizzo IP passato,
// che andrà poi convertito nel tipo di rete opportuno

if(!(status = gethostbyaddr(nome, ipaddress))
//gli passo sia il nome che l'indirizzo perché durante l'interrogazione al DNS
//devo verificare che esista un'effettiva corrispondenza tra indirizzo e nome
Changed lines 97-98 from:
perror("resolver non presente");
to:
//...nel caso non esista corrispondenza, il programma esce visualizzando l'errore
perror("Resolver
non presente");
Added line 103:
//...se invece esiste corrispondenza, stampa a video il nome
Changed lines 112-114 from:
// voglio andare dal nome all'indirizzo IP
//
andrà poi convertito nel tipo di rete opportuno
to:
// Voglio ora ottenere l'indirizzo IP dal nome passato,
// che andrà poi convertito nel tipo di rete opportuno
Added line 117:
//anche in questo caso vale lo stesso discorso delle corrispondenze fatto prima
Changed line 119 from:
perror("resolver non presente");
to:
perror("Resolver non presente");
Added line 124:
//...se invece esiste corrispondenza, stampa a video l'indirizzo IP
Deleted line 129:
Added line 131:
Changed lines 137-138 from:
@]\\
to:
@]
Changed line 177 from:
In HTTP/1.0 ogni immagine o altro file è caricato come connessione differente. Quindi avrò 10 connessioni.\\
to:
In HTTP/1.0 ogni immagine o altro file è caricato come connessione differente. Quindi avrò 10 connessioni per ogni mmagine più una per la pagina richiesta, quindi 11 totali.\\
Changed lines 146-149 from:
GET www.dti.unimi.it/default.htm HTTP/1.0\\
Host: dti.unimi.it\\
Connection: close\\\
to:
''GET'' www.dti.unimi.it/default.htm HTTP/1.0\\
''Host'': dti.unimi.it\\
''Connection'': close\\\
Changed lines 151-155 from:
GET: /default.htm HTTP/1.1\\
Host: www.dti.unimi.it\\
Range: bytes 0-300\\
Connection: close\\\
to:
''GET'' /default.htm HTTP/1.1\\
''Host'': www.dti.unimi.it\\
''Range'': bytes 0-300\\
''Connection'': close\\\
Changed lines 151-153 from:
GET: /default.htm HTTP/1.1
Host: www.dti.unimi.it
Range: bytes 0-300
to:
GET: /default.htm HTTP/1.1\\
Host: www.dti.unimi.it\\
Range: bytes 0-300\\
Changed lines 79-80 from:
L'implementazione di nslookup che propongo legge un argomento (opzione) da linea di comando: se è "-d" chiama gethostbyname(), se è "-i" chiama gethostbyaddr(). (nslookup non ha bisogno in realtà di queste opzioni, dal momento che se gli do un nome mi restituisce l'ip e viceversa).
to:
L'implementazione di nslookup che propongo legge un argomento (opzione) da linea di comando: se è "-d" chiama gethostbyaddr(), se è "-i" chiama gethostbyname(). (nslookup non ha bisogno in realtà di queste opzioni, dal momento che se gli do un nome mi restituisce l'ip e viceversa).
Changed lines 88-89 from:
// andrà poi convertito nel tipo di rete opportuno
to:
// andrà poi convertito nel tipo di rete opportuno
Changed lines 106-107 from:
// andrà poi convertito nel tipo di rete opportuno
to:
// andrà poi convertito nel tipo di rete opportuno
Added line 145:
'''prima richiesta:'''\\
Changed lines 150-153 from:
%warning%'''WARNING'''\\
La seconda parte va fatta con FTP?
to:
'''seconda richiesta:'''\\
GET: /default.htm HTTP/1.1
Host: www.dti.unimi.it
Range: bytes 0-300
Connection: close\\\
Changed lines 163-168 from:
...


%warning%'''WARNING'''\\
Penso che si faccia con i COOKIE però non so come metterlo giù
to:
Una tecnica per risolvere questo problema è quella dei cookie. I cookie sono file testuali contenenti attributi per simulare lo stato di una sessione HTTP. Possono servire per: informazioni generali (pagine visitate, prodotti cercati, preferenze, ecc / autenticazione senza ripetere il login.\\
Immaginiamo che in fondo alla pagina dopo i 3 form ci sarà un tasto di ''invio'', quindi se l'utente compila tutte e tre le form le informazioni vengono inviate e salvate sul server.\\
Mentre se l'utente compila solo parzialmente i form sul server non viene salvato nulla, ma vengono utilizzati i cookie che conterranno le informazioni parziali inserite dall'utente. La prossima volta che l'utente accederà alla pagina il client controllerà la presenza dei cookie, se li rileva inserisce le informazioni nei vari campi compilati precedentemente.\\\
Changed lines 33-34 from:
status = select (0, &sockset, NULL, NULL, NULL);
to:
status = select (0, &sockset, NULL, NULL, NULL);//il 3° NULL è perchè dò per scontato che non ci siano richieste
//in attesa
Changed lines 54-55 from:
status = select (0, &sockset, NULL, NULL, NULL);
to:
status = select (0, &sockset, NULL, NULL, NULL);//il 3° NULL è perchè dò per scontato che non ci siano richieste
//in attesa
Changed line 90 from:
if(!(status = gethostbyaddr(nome, ipaddress))
to:
if(!(status = gethostbyaddr(nome, ipaddress))//ne chiama 2 perchè controlla che si sia l'ind corrispondente
Added lines 120-121:

L'interfaccia è così implementata: ''(viene qui scritta anche se non era richiesta)''
Changed line 145 from:
GET /default.htm HTTP/1.0\\
to:
GET www.dti.unimi.it/default.htm HTTP/1.0\\
Changed lines 141-145 from:
GET /default.htm HTTP/1.0
Host: dti.unimi.it
Connection: close
to:
GET /default.htm HTTP/1.0\\
Host: dti.unimi.it\\
Connection: close\\\
Changed lines 141-142 from:
...
to:
GET /default.htm HTTP/1.0
Host: dti
.unimi.it
Connection: close


%warning%'''WARNING'''\\
La seconda parte va fatta con FTP?
Changed lines 137-138 from:
Scrivete una richiesta sul server www.dti.unimi-it per la URL radice /, ma soltanto i byte da 0 a 300.'''
to:
Scrivete una richiesta sul server www.dti.unimi.it per la URL radice /, ma soltanto i byte da 0 a 300.'''
Added lines 152-155:

%warning%'''WARNING'''\\
Penso che si faccia con i COOKIE però non so come metterlo giù
Changed lines 160-161 from:
...
to:
'''1.'''\\
In HTTP/1
.0 ogni immagine o altro file è caricato come connessione differente. Quindi avrò 10 connessioni.\\
Invece in HTTP/1.1 viene fatto un ''multiple-get'' nella stessa connessione. Quindi avrò un unica connessione.\\
{+ ''NOTA HTTP:'' +} se faccio connessioni web corte ( HTTP/1.0 ) non do il tempo di arrivare ad una dimensione ottimale della finestra, mentre con HTTP/1.1 arrivo prima ad una finestra ottimale TCP di connessione.\\
Infatti minore è la dimensione delle immagini, minore è la differenza tra HTTP/1.0 e HTTP/1.1. Se sono "grosse" fa differenza perché passo più tempo al livello ottimale della finestra.\\\

'''2.'''\\
Il protocollo IMAP ( Internet Messagge Access Protocol ) è un’alternativa a POP3.\\
Come POP3 definisce un’astrazione nota come casella postale, posta sul computer server. L’utente attiva un client IMAP che contatta il server per recuperare i messaggi.\\
La '''diversità''' tra i due protocolli sta nel fatto che IMAP permette di creare, cancellare o rinominare dinamicamente le caselle postali. IMAP fornisce inoltre una funzionalità estesa per il recupero e l’elaborazione dei messaggi. L’utente può ottenere informazioni su un messaggio o esaminare i campi dell’intestazione senza recuperare l’intero messaggio; inoltre, può cercare una stringa specificata e riprendere parti specifiche di un messaggio.\\
''(dal libro)''\\\

'''3.'''\\
IIOP ( Internet Inter-ORB Protocol ) è un programma basato su CORBA ed è una particolare implementazione del protocollo GIOP che si avvale del protocollo TCP/IP per la realizzazione dello strato di trasporto dei messaggi tra oggetti remoti.\\
{+ ''NOTA:'' +} Non mi pare che abbia mai fatto questa parte (o magari mentre la faceva stavo giocando a Quake :p). Però a %newwin%[[http://www.mokabyte.it/1998/12/iiop.htm | questo]] link trovate qualche spiegazione interessante sul protocollo GIOP e IIOP
.
Changed line 155 from:
# '''Se una pagina Web contiene 10 tag <img ...> quante connessioi TCP verranno aperte con http1.0 quando si accede alla pagina? quante con ghttp 1.1?'''
to:
# '''Se una pagina Web contiene 10 tag <img ...> quante connessioni TCP verranno aperte con http1.0 quando si accede alla pagina? quante con http 1.1?'''
Changed lines 84-85 from:
ipaddress = argv[2]; // memorizzo l'ipaddress passato da linea di comando. Nell'opzione voglio andare
// dall'indirizzo IP al nome
to:
ipaddress = argv[2]; // memorizzo l'ipaddress passato da linea di comando. Nell'opzione
// voglio andare dall'indirizzo IP al nome
Changed lines 102-103 from:
nome = argv[2]; // memorizzo il nome passato da linea di comando.In questa opzione voglio andare dal nome
// all'indirizzo IP
to:
nome = argv[2]; // memorizzo il nome passato da linea di comando.In questa opzione
// voglio andare dal nome all'indirizzo IP
Added line 130:
Changed lines 123-124 from:
to:
@]\\
Changed lines 130-133 from:
* Scopriamo runtime un interfaccia nota, è una chiamata {+ statica +}. C'è una identificazione runtime delle porte dell'interfaccia.
@]
to:
* Scopriamo runtime un interfaccia nota, è una chiamata {+ statica +}. C'è una identificazione runtime delle porte dell'interfaccia.\\\
Changed lines 102-103 from:
nome = argv[2]; // memorizzo il nome passato da linea di comando
to:
nome = argv[2]; // memorizzo il nome passato da linea di comando.In questa opzione voglio andare dal nome
// all'indirizzo IP
Added lines 117-129:

interface { uiid 12345 ...
/* interfaccia in IDL per il DNS */
[out] int status gethostbyname ( [in] string nome, [in]ipaddress )
...
}

# Uso rpcgen su idl e ottengo stub.o e skeleton.o
# link stub.o con client.o dove client è qualunque programma che chiamava la gethostbyname ( ottengo clientrpc.exe)
# link di skeleton.o con server.o ( oggetto sulla socket library remota ) ottenuto dalla socjet library su macchina server, ottengo serverrpc.exe
# registro l'interfaccia con portmapper; lancio server ( serve perché così chi chiama trova la porta giusta )
# uso clientrpc.exe al posto del vecchio client.exe
* Scopriamo runtime un interfaccia nota, è una chiamata {+ statica +}. C'è una identificazione runtime delle porte dell'interfaccia.
Changed lines 84-85 from:
ipaddress = argv[2]; // memorizzo l'ipaddress passato da linea di comando
to:
ipaddress = argv[2]; // memorizzo l'ipaddress passato da linea di comando. Nell'opzione voglio andare
// dall'indirizzo IP al nome
Changed line 88 from:
if(!(status = gethostbyaddr(nome, ipaddr))
to:
if(!(status = gethostbyaddr(nome, ipaddress))
Changed line 105 from:
if(!(status = gethostbyname(nome, ipaddr))
to:
if(!(status = gethostbyname(nome, ipaddress))
Changed lines 118-119 from:
[segue]
to:
Changed lines 146-147 from:
to:
...
Added lines 145-146:
%red%[-'''SOLUZIONE'''-]
Added lines 144-146:

----
Added lines 139-143:

!!Domande:
# '''Se una pagina Web contiene 10 tag <img ...> quante connessioi TCP verranno aperte con http1.0 quando si accede alla pagina? quante con ghttp 1.1?'''
# '''Spiegare la differenza tra i protocolli POP e IMAP'''
# '''Cos'è IIOP e che ruolo ha nel protocollo CORBA?'''
Changed line 18 from:
/* QUI IL PROCESSO FIGLIO GESTISCE IL DIALOGO; USANDO IL;DESCRITTORE 'nsd' */
to:
/* QUI IL PROCESSO FIGLIO GESTISCE IL DIALOGO USANDO IL DESCRITTORE 'nsd' */
Changed lines 71-72 from:
'''La più semplice API verso il DNS è quella fornita dalla socket library con le chiamate gethostbyname()e gethostbyaddr(. Spiegatene il significato e usatele per scrivere lo pseudocodice di un programma che fornisca la stessa funzionalità di query diretta del comando nslookup.'''
to:
'''La più semplice API verso il DNS è quella fornita dalla socket library con le chiamate gethostbyname()e gethostbyaddr(). Spiegatene il significato e usatele per scrivere lo pseudocodice di un programma che fornisca la stessa funzionalità di query diretta del comando nslookup.'''
Changed lines 75-76 from:
...
to:
La chiamata gethostbyname() riceve una struttura con il nome DNS di un host e ne restituisce una sockaddr. La chiamata gethostbyaddr() fa l'esatto contrario.

L'implementazione di nslookup che propongo legge un argomento (opzione) da linea di comando: se è "-d" chiama gethostbyname(), se è "-i" chiama gethostbyaddr()
. (nslookup non ha bisogno in realtà di queste opzioni, dal momento che se gli do un nome mi restituisce l'ip e viceversa).

[@
String *nome, *ipaddress; // per comodità non li gestisco come struct ma come string

if(argv[1] == "-d") // traduzione diretta: in realtà dovrei fare uno strcmp
{
ipaddress = argv[2]; // memorizzo l'ipaddress passato da linea di comando
// andrà poi convertito nel tipo di rete opportuno

if(!(status = gethostbyaddr(nome, ipaddr))
{
perror("resolver non presente");
exit(-1);
}
else
{
printf("%s", nome);
exit(0);
}
}

else if(argv[1] == "-i")
{
nome = argv[2]; // memorizzo il nome passato da linea di comando
// andrà poi convertito nel tipo di rete opportuno

if(!(status = gethostbyname(nome, ipaddr))
{
perror("resolver non presente");
exit(-1);
}
else
{
printf("%s", ipaddress);
exit(0);
}
}
@]

[segue]
Changed lines 44-47 from:
Da notare che se con la accept avevo un unico socket attivo, con la select ne avrò più di uno contemporaneamente. Inoltre, mentre la accept garantiva la simultaneità (più client serviti alla volta) grazie alla fork, con la select ho un unico processo in esecuzione, che può dunque servire un solo handleTCP per volta.

Tuttavia, nulla mi impedisce di utilizzare una fork anche la select, aggiugendola prima della chiamata di funzione. In questo modo garantisco sì la simultaneità, ma non è poi così indispensabile dato che quando uso la select è generalmente perché ho pochi socket da gestire. In generale vale la pena di usare una fork anche nella select solo quando il tempo di servizio è alto.
to:
Da notare che se con la accept avevo un unico socket attivo, con la select ne avrò più di uno contemporaneamente. Inoltre, se la accept garantiva la simultaneità grazie alla fork (più client serviti alla volta), con la select ho invece un unico processo in esecuzione (che può dunque servire un solo handleTCP per volta).

Tuttavia, nulla mi impedisce di utilizzare una fork anche nella select. In questo modo avrei sì la simultaneità, ma non è poi così indispensabile dato che usiamo la select quando ci sono pochi socket da gestire. Può avere un senso solo quando il tempo di servizio è alto, così invece di dover eseguire più volte lo stesso servizio (facendo aspettare gli altri client) lo smisto su processi diversi simultaneamente.
Deleted line 32:
// chiamata bloccante: rileva solo la presenza dei dati sul primo socket pronto
Changed lines 34-35 from:
to:
// è una chiamata bloccante: rileva solo la presenza dei dati sul primo socket pronto
Changed lines 30-31 from:
...
to:
Lato server dovrò creare tre socket e memorizzarli in un array ''sockset''. A questo punto faccio la select:

[@
// chiamata bloccante: rileva solo la presenza dei dati sul primo socket pronto
status = select (0, &sockset, NULL, NULL, NULL);

// INIZIO CICLO SUI SOCKET DI SOCKSET

if (FD_ISSET (sockset[i], &sockset)) //verifica per ogni socket che siano arrivati dati
handleTCPservice(socket[i]); //se sì, chiama la funzione richiesta

// FINE CICLO
@]

Da notare che se con la accept avevo un unico socket attivo, con la select ne avrò più di uno contemporaneamente
. Inoltre, mentre la accept garantiva la simultaneità (più client serviti alla volta) grazie alla fork, con la select ho un unico processo in esecuzione, che può dunque servire un solo handleTCP per volta.

Tuttavia, nulla mi impedisce di utilizzare una fork anche la select, aggiugendola prima della chiamata di funzione. In questo modo garantisco sì la simultaneità, ma non è poi così indispensabile dato che quando uso la select è generalmente perché ho pochi socket da gestire. In generale vale la pena di usare una fork anche nella select solo quando il tempo di servizio è alto.

Come si implementa?

[@
// CICLO PRIMARIO DI SELECT

status = select (0, &sockset, NULL, NULL, NULL);

// CICLO SECONDARIO SUI SOCKET DI SOCKSET

for(i=0; i<=2; i++)
if(FD_ISSET (sockset[i], &sockset)) //se c'è almeno un socket pronto...
if((c = fork()) == 0) //...fai una fork, e nel processo figlio...
handleTCPservice(sockset[i]); //...esegui il servizio chiamato
//il socket verrà chiuso dentro la procedura di servizio

// FINE CICLO SECONDARIO

// FINE CICLO PRIMARIO
@]
Added lines 1-61:
(:title Temi d'esame di Sistemi - 9/9/2005:)
[[Torna alla pagina di Sistemi Anticoncezionali delle Reti e dei Damiani->Sistemi]]
----

%titolo%''':: Temi d'esame di Sistemi - 9/9/2005 ::'''

!!Esercizio 1
'''Un server TCP a connessione multipla è stato usando con la socket library come segue:'''

[@
listen(sd,5); /* AL PIU’ 5 CONNESSIONI */
do
{
nsd = accept(sd,&(work.s),&addrlen);
pid = fork();
if (pid == 0)
{
/* QUI IL PROCESSO FIGLIO GESTISCE IL DIALOGO; USANDO IL;DESCRITTORE 'nsd' */
close(nsd);
exit(0); /* end of child process */
}
else close(nsd); /* IL PADRE NON USA 'nsd' */
} while(1);
@]

'''Fornire lo pseudocodice di un’implementazione alternativa che usi la chiamata select() supponendo che il numero massimo dei possibili client sia pari a 3 e che il loro indirizzo di rete e porta siano noti a priori.'''

%red%[-'''SOLUZIONE'''-]

...

----

!!Esercizio 2
'''La più semplice API verso il DNS è quella fornita dalla socket library con le chiamate gethostbyname()e gethostbyaddr(. Spiegatene il significato e usatele per scrivere lo pseudocodice di un programma che fornisca la stessa funzionalità di query diretta del comando nslookup.'''

%red%[-'''SOLUZIONE'''-]

...

----

!!Esercizio 3
'''Scrivete una richiesta HTTP/1.0 per la pagina default.htm sul server www.dti.unimi.it\\
Scrivete una richiesta sul server www.dti.unimi-it per la URL radice /, ma soltanto i byte da 0 a 300.'''

%red%[-'''SOLUZIONE'''-]

...

----

!!Esercizio 4
'''Un sito Web di grande successo offre la registrazione degli utenti alla URL http://ebusiness.com/register.htm. Poichè la procedura consiste di 3 form da compilare una dopo l’altra, si vuol permettere all’utente di abbandonare la procedura di registrazione in ogni momento per riprendere quando lo desidera. Per evitare di sprecare risorse sul server, si desidera memorizzare lato server le sole registrazioni complete. Illustrate una tecnica vostra scelta per risolvere il problema.'''

%red%[-'''SOLUZIONE'''-]

...

----
[[Torna alla pagina di Sistemi Anticoncezionali delle Reti e dei Damiani->Sistemi]]