-\begin{figure}[!htbp]
- \footnotesize
- \begin{lstlisting}{}
-#include <sys/types.h> /* predefined types */
-#include <unistd.h> /* include unix standard library */
-#include <arpa/inet.h> /* IP addresses conversion utiliites */
-#include <sys/socket.h> /* socket library */
-#include <stdio.h> /* include standard I/O library */
-#include <time.h>
-#define MAXLINE 80
-#define BACKLOG 10
-int main(int argc, char *argv[])
-{
-/*
- * Variables definition
- */
- int list_fd, conn_fd;
- int i;
- struct sockaddr_in serv_add;
- char buffer[MAXLINE];
- time_t timeval;
- ...
- /* create socket */
- if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("Socket creation error");
- exit(-1);
- }
- /* initialize address */
- memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
- serv_add.sin_family = AF_INET; /* address type is INET */
- serv_add.sin_port = htons(13); /* daytime port is 13 */
- serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */
- /* bind socket */
- if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
- perror("bind error");
- exit(-1);
- }
- /* listen on socket */
- if (listen(list_fd, BACKLOG) < 0 ) {
- perror("listen error");
- exit(-1);
- }
- /* write daytime to client */
- while (1) {
- if ( (conn_fd = accept(list_fd, (struct sockaddr *) NULL, NULL)) <0 ) {
- perror("accept error");
- exit(-1);
- }
- timeval = time(NULL);
- snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
- if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) {
- perror("write error");
- exit(-1);
- }
- close(conn_fd);
- }
- /* normal exit */
- exit(0);
-}
- \end{lstlisting}
- \caption{Esempio di codice di un semplice server per il servizio daytime.}
- \label{fig:net_serv_code}
-\end{figure}
+Normalmente si dividono i server in due categorie principali, e vengono detti
+\textsl{concorrenti} o \textsl{iterativi}, sulla base del loro comportamento.
+Un \textsl{server iterativo} risponde alla richiesta inviando i dati e resta
+occupato e non rispondendo ad ulteriori richieste fintanto che non ha fornito
+una risposta alla richiesta. Una volta completata la risposta il server
+diventa di nuovo disponibile.
+
+Un \textsl{server concorrente} al momento di trattare la richiesta crea un
+processo figlio (o un thread) incaricato di fornire i servizi richiesti, per
+porsi immediatamente in attesa di ulteriori richieste. In questo modo, con
+sistemi multitasking, più richieste possono essere soddisfatte
+contemporaneamente. Una volta che il processo figlio ha concluso il suo lavoro
+esso di norma viene terminato, mentre il server originale resta sempre attivo.
+
+
+\subsection{Il modello \textit{peer-to-peer}}
+\label{sec:net_peertopeer}
+
+Come abbiamo visto il tratto saliente dell'architettura \textit{client-server}
+è quello della preminenza del server rispetto ai client, le architetture
+\textit{peer-to-peer} si basano su un approccio completamente opposto che è
+quello di non avere nessun programma che svolga un ruolo preminente.
+
+Questo vuol dire che in generale ciascun programma viene ad agire come un nodo
+in una rete potenzialmente paritetica; ciascun programma si trova pertanto a
+ricevere ed inviare richieste ed a ricevere ed inviare risposte, e non c'è più
+la separazione netta dei compiti che si ritrova nelle architetture
+\textit{client-server}.
+
+Le architetture \textit{peer-to-peer} sono salite alla ribalta con
+l'esplosione del fenomeno Napster, ma gli stessi protocolli di routing sono un
+buon esempio di architetture \textit{peer-to-peer}, in cui ciascun nodo,
+tramite il demone che gestisce il routing, richiede ed invia informazioni ad
+altri nodi.
+
+In realtà in molti casi di architetture classificate come \textit{peer-to-peer}
+non è detto che la struttura sia totalmente paritetica e ci sono parecchi
+esempi in cui alcuni servizi vengono centralizzati o distribuiti
+gerarchicamente, come per lo stesso Napster, in cui le ricerche venivano
+effettuate su un server centrale.
+
+
+
+\subsection{Il modello \textit{three-tier}}
+\label{sec:net_three_tier}
+
+Benché qui sia trattato a parte, il modello \textit{three-tier} in realtà è
+una estensione del modello \textit{client-server}. Con il crescere della
+quantità dei servizi forniti in rete (in particolare su internet) ed al numero
+di accessi richiesto. Si è così assistito anche ad una notevole crescita di
+complessità, in cui diversi servizi venivano ad essere integrati fra di loro.
+
+In particolare sempre più spesso si assiste ad una integrazione di servizi di
+database con servizi di web, in cui le pagine vengono costruite dinamicamente
+sulla base dei dati contenuti nel database. In tutti questi casi il problema
+fondamentale di una architettura \textit{client-server} è che la richiesta di
+un servizio da parte di un gran numero di client si scontra con il collo di
+bottiglia dell'accesso diretto ad un unico server, con gravi problemi di
+scalabilità.
+
+Rispondere a queste esigenze di scalabilità il modello più semplice (chiamato
+talvolta \textit{two-tier}) da adottare è stata quello di distribuire il
+carico delle richieste su più server identici, mantenendo quindi
+sostanzialmente inalterata l'architettura \textit{client-server} originale.
+
+Nel far questo ci si scontra però con gravi problemi di manutenibilità dei
+servizi, in particolare per quanto riguarda la sincronizzazione dei dati, e di
+inefficienza dell'uso delle risorse. Il problema è particolarmente grave ad
+esempio per i database che non possono essere replicati e sincronizzati
+facilmente, e che sono molto onerosi, la loro replicazione è costosa e
+complessa.
+
+È a partire da queste problematiche che nasce il modello \textit{three-tier},
+che si struttura, come dice il nome, su tre livelli. Il primo livello, quello
+dei client che eseguono le richieste e gestiscono l'interfaccia con l'utente,
+resta sostanzialmente lo stesso del modello \textit{client-server}, ma la
+parte server viene suddivisa in due livelli, introducendo un
+\textit{middle-tier}, su cui deve appoggiarsi tutta la logica di analisi delle
+richieste dei client per ottimizzare l'accesso al terzo livello, che è quello
+che si limita a fornire i dati dinamici che verranno usati dalla logica
+implementata nel \textit{middle-tier} per eseguire le operazioni richieste dai
+client.
+
+In questo modo si può disaccoppiare la logica dai dati, replicando la prima,
+che è molto meno soggetta a cambiamenti ed evoluzione, e non soffre di
+problemi di sincronizzazione, e centralizzando opportunamente i secondi. In
+questo modo si può distribuire il carico ed accedere in maniera efficiente i
+dati.