+\section{Il modello client-server}
+\label{sec:net_cliserv}
+
+La differenza principale fra un'applicazione di rete e un programma normale è
+che quest'ultima per definizione concerne la comunicazione fra ``processi''
+diversi (che in generale non girano neanche sulla stessa macchina). Questo già
+prefigura un cambiamento completo rispetto all'ottica del ``programma''
+monolitico all'interno del quale vengono eseguite tutte le istruzioni, e
+presuppone un sistema operativo ``multitasking'' in grado di eseguire processi
+diversi.
+
+Il concetto fondamentale si basa la programmazione di rete sotto Linux (e
+sotto Unix in generale) è il modello \textit{client-server} in cui un
+programma di servizio, il \textit{server} riceve un connessione e risponde a
+un programma di utilizzo, il \textit{client}, provvedendo a quest'ultimo un
+definito insieme di servizi.
+
+Esempi di questo modello sono il WEB, ftp, telnet, ssh e praticamente ogni
+servizio che viene fornito tramite la rete, ma il modello è utilizzato in
+generale anche per programmi che non fanno necessariamente uso della rete,
+come il sistema a finestre.
+
+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 (non rispondendo ad ulteriori richieste) fintanto che non ha concluso
+la richiesta. Una volta completata la richiesta il server diventa di nuovo
+disponibile.
+
+Un \textsl{server concorrente} al momento di trattare la richiesta crea un
+processo figlio incaricato di fornire i servizi richiesti, per poi porsi in
+attesa di ulteriori richieste. In questo modo più richieste possono essere
+soddisfatte contemporaneamente; una volta che il processo figlio ha concluso
+il suo lavoro viene terminato, mentre il server originale resta sempre attivo.
+
+
+\subsection{Un primo esempio di client}
+\label{sec:net_cli_sample}
+
+Per evitare di rendere l'esposizione dei concetti generali sulla rete
+puramente teorica iniziamo con il mostrare un esempio di un client TCP
+elementare. Scopo di questo esempio è fornire un primo approccio alla
+programmazione di rete, tutto questo sarà esaminato in dettaglio nei capitoli
+successivo; qui ci limiteremo a introdurre la nomenclatura senza fornire
+definizioni precise e dettagli di funzionamento che saranno trattati
+estensivamente più avanti.
+
+In \nfig\ è riportata la sezione principale del codice del nostro client
+elementare per il servizio \textit{daytime}, un servizio standard che
+restituisce l'ora locale della macchina a cui si effettua la richiesta.
+
+
+\begin{figure}[!htb]
+ \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 */
+
+int main(int argc, char *argv[])
+{
+ int sock_fd;
+ int i, nread;
+ struct sockaddr_in serv_add;
+ char buffer[MAXLINE];
+ ...
+ /* create socket */
+ if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ perror("Socket creation error");
+ return -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 post is 13 */
+ /* build address using inet_pton */
+ if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) {
+ perror("Address creation error");
+ return -1;
+ }
+ /* extablish connection */
+ if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+ perror("Connection error");
+ return -1;
+ }
+ /* read daytime from server */
+ while ( (nread = read(sock_fd, buffer, MAXLINE)) > 0) {
+ buffer[nread]=0;
+ if (fputs(buffer, stdout) == EOF) { /* write daytime */
+ perror("fputs error");
+ return -1;
+ }
+ }
+ /* error on read */
+ if (nread < 0) {
+ perror("Read error");
+ return -1;
+ }
+ /* normal exit */
+ return 0;
+}
+ \end{lstlisting}
+ \caption{Esempio di codice di un client elementare per il servizio daytime.}
+ \label{fig:net_cli_code}
+\end{figure}
+
+Il sorgente completo del programma (\texttt{ElemDaytimeTCPClient.c}, che
+comprende il trattamento delle opzioni e una funzione per stampare un
+messaggio di aiuto) è allegato alla guida nella sezione dei codici sorgente e
+può essere compilato su una qualunque macchina Linux.
+
+Il programma anzitutto include gli header necessari (\texttt{\small 1--5});
+dopo la dichiarazione delle variabili (\texttt{\small 9--12}) si è omessa
+tutta la parte relativa al trattamento degli argomenti passati dalla linea di
+comando (effettuata con le apposite routines illustrate in
+\capref{sec:proc_opt_handling}).
+
+Il primo passo (\texttt{\small 14--18}) è creare un \textit{socket} IPv4
+(\texttt{AF\_INET}), di tipo TCP \texttt{SOCK\_STREAM} (in sostanza un canale
+di comunicazione attraverso internet, questi termini verranno spiegati con
+precisione più avanti). La funzione \texttt{socket} ritorna un descrittore,
+analogo a quello dei file, che viene usato per identificare il socket in tutte
+le chiamate successive. Nel caso la chiamata fallisca si stampa un errore con
+la relativa routine e si esce.
+
+Il passo seguente (\texttt{\small 19--27}) è quello di costruire una apposita
+struttura \texttt{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed
+il numero della porta del servizio. Il primo passo è inizializzare tutto a
+zero, per poi inserire il tipo di protocollo e la porta (usando per
+quest'ultima la funzione \texttt{htons} per convertire il formato dell'intero
+usato dal computer a quello usato nella rete), infine si utilizza la funzione
+\texttt{inet\_pton} per convertire l'indirizzo numerico passato dalla linea di
+comando.
+
+Usando la funzione \texttt{connect} sul socket creato in precedenza
+(\texttt{\small 28--32}) si provvede poi a stabilire la connessione con il
+server specificato dall'indirizzo immesso nella struttura passata come secondo
+argomento, il terzo argomento è la dimensione di detta struttura. Dato che
+esistono diversi tipi di socket, si è dovuto effettuare un cast della
+struttura inizializzata in precedenza, che è specifica per i socket IPv4. Un
+valore di ritorno negativo implica il fallimento della connessione.
+
+Completata con successo la connessione il passo successivo (\texttt{\small
+ 34--40}) è leggere la data dal socket; il server invierà sempre una stringa
+di 26 caratteri della forma \verb|Wed Apr 4 00:53:00 2001\r\n|, che viene
+letta dalla funzione \texttt{read} e scritta su \texttt{stdout}.
+
+Dato il funzionamento di TCP la risposta potrà tornare in un unico pacchetto
+di 26 byte (come avverrà senz'altro nel caso in questione) ma potrebbe anche
+arrivare in 26 pacchetti di un byte. Per questo nel caso generale non si può
+mai assumere che tutti i dati arrivino con una singola lettura, pertanto
+quest'ultima deve essere effettuata in un loop in cui si continui a leggere
+fintanto che la funzione \texttt{read} non ritorni uno zero (che significa che
+l'altro capo ha chiuso la connessione) o un numero minore di zero (che
+significa un errore nella connessione).
+
+Si noti come in questo caso la fine dei dati sia specificata dal server che
+chiude la connessione; questa è una delle tecniche possibili (è quella usata
+pure dal protocollo HTTP), ma ce ne possono essere altre, ad esempio FTP marca
+la conclusione di un blocco di dati con la sequenza ASCII \verb|\r\n|
+(carriage return e line feed), mentre il DNS mette la lunghezza in testa ad
+ogni blocco che trasmette. Il punto essenziale è che TCP non provvede nessuna
+indicazione che permetta di marcare dei blocchi di dati, per cui se questo è
+necessario deve provvedere il programma stesso.
+
+\subsection{Un primo esempio di server}
+\label{sec:net_serv_sample}
+
+Dopo aver illustrato il client daremo anche un esempio di un server
+elementare, in grado di rispondere al precedente client. Il listato è
+nuovamente mostrato in \nfig, il sorgente completo
+(\texttt{ElemDaytimeTCPServer.c}) è allegato insieme agli altri file nella
+directory \texttt{sources}.
+
+\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}
+
+Come per il client si includono gli header necessari a cui è aggiunto quello
+per trattare i tempi, e si definiscono alcune costanti e le variabili
+necessarie in seguito (\texttt{\small 1--18}), come nel caso precedente si
+sono omesse le parti relative al trattamento delle opzioni da riga di comando.
+
+La creazione del socket (\texttt{\small 22--26}) è analoga al caso precedente,
+come pure l'inizializzazione della struttura \texttt{sockaddr\_in}, anche in
+questo caso si usa la porta standard del servizio daytime, ma come indirizzo
+IP si il valore predefinito \texttt{INET\_ANY} che corrisponde ad un indirizzo
+generico (\texttt{\small 27--31}).
+
+Si effettua poi (\texttt{\small 32--36}) la chiamata alla funzione
+\texttt{bind} che permette di associare la precedente struttura al socket, in
+modo che quest'ultimo possa essere usato per accettare connessioni su una
+qualunque delle interfacce di rete locali.
+
+Il passo successivo (\texttt{\small 37--41}) è mettere ``in ascolto'' il
+socket, questo viene effettuato con la funzione \texttt{listen} che dice al
+kernel di accettare connessioni per il socket specificato, la funzione indica
+inoltre, con il secondo parametro, il numero massimo di connessioni che il
+kernel accetterà di mettere in coda per il suddetto socket.
+
+Questa ultima chiamata completa la preparazione del socket per l'ascolto (che
+viene chiamato anche \textit{listening descriptor}) a questo punto il processo
+è mandato in sleep (\texttt{\small 44--47}) con la successiva chiamata alla
+funzione \texttt{accept}, fin quando non arriva e viene accettata una
+connessione da un client.
+
+Quando questo avviene \texttt{accept} ritorna un secondo descrittore di
+socket, che viene chiamato \textit{connected descriptor} che è quello che
+viene usato dalla successiva chiamata alla \texttt{write} per scrivere la
+risposta al client, una volta che si è opportunamente (\texttt{\small 48--49})
+costruita la stringa con la data da trasmettere. Completata la trasmissione il
+nuovo socket viene chiuso (\texttt{\small 54}).
+Il tutto è inserito in un loop infinito (\texttt{\small 42--55}) in modo da
+poter ripetere l'invio della data ad una successiva connessione.
+
+È importante notare che questo server è estremamente elementare, infatti a
+parte il fatto di essere dipendente da IPv4, esso è in grado di servire solo
+un client alla volta, è cioè un \textsl{server iterativo}, inoltre esso è
+scritto per essere lanciato da linea di comando, se lo si volesse utilizzare
+come demone di sistema (che è in esecuzione anche quando non c'è nessuna shell
+attiva e il terminale da cui lo si è lanciato è stato sconnesso),
+occorrerebbero delle opportune modifiche.