+ operazioni di lettura per accumulare dati sufficienti, si può lasciare al
+ kernel il compito di impostare un minimo al di sotto del quale il file
+ descriptor, pur avendo disponibili dei dati, non viene dato per pronto in
+ lettura.}
+
+
+
+\subsection{Un esempio di I/O multiplexing}
+\label{sec:TCP_multiplex_example}
+
+Abbiamo incontrato la problematica tipica che conduce all'uso dell'I/O
+multiplexing nella nostra analisi degli errori in
+\secref{sec:TCP_conn_early_abort}, quando il nostro client non era in grado di
+rendersi conto di errori sulla connessione essendo impegnato nella attesa di
+dati in ingresso dallo standard input.
+
+In questo caso il problema è quello di dover tenere sotto controllo due
+diversi file descriptor, lo standard input, da cui viene letto il testo che
+vogliamo inviare al server, e il socket connesso con il server su cui detto
+testo sarà scritto e dal quale poi si vorrà ricevere la risposta. L'uso
+dell'I/O multiplexing consente di tenere sotto controllo entrambi, senza
+restare bloccati.
+
+Nel nostro caso quello che ci interessa è non essere bloccati in lettura sullo
+standard input in caso di errori sulla connessione o chiusura della stessa da
+parte del server. Entrambi questi casi possono essere rilevati usando
+\func{select}, per quanto detto in \secref{sec:TCP_sock_select}, mettendo
+sotto osservazione i file descriptor per la condizione di essere pronti in
+lettura: sia infatti che si ricevano dati, che la connessione sia chiusa
+regolarmente (con la ricezione di un segmento FIN) che si riceva una
+condizione di errore (con un segmento RST) il socket connesso sarà pronto in
+lettura (nell'ultimo caso anche in scrittura, ma questo non è necessario ai
+nostri scopi).
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15.6cm}
+ \includecodesample{listati/ClientEcho_third.c}
+ \end{minipage}
+ \normalsize
+ \caption{La sezione nel codice della terza versione della funzione
+ \func{ClientEcho} usata dal client per il servizio \textit{echo}
+ modificata per l'uso di \func{select}.}
+ \label{fig:TCP_ClientEcho_third}
+\end{figure}
+
+Riprendiamo allora il codice del client, modificandolo per l'uso di
+\func{select}. Quello che dobbiamo modificare è la funzione \func{ClientEcho}
+di \figref{fig:TCP_ClientEcho_second}, dato che tutto il resto, che riguarda
+le modalità in cui viene stabilita la connessione con il server, resta
+assolutamente identico. La nostra nuova versione di \func{ClientEcho}, la
+terza della serie, è riportata in \figref{fig:TCP_ClientEcho_third}.
+
+In questo caso la funzione comincia (\texttt{\small 8--9}) con la
+cancellazione del file descriptor set \var{fset} e del valore \var{maxfd} da
+passare a \func{select} come massimo per il numero dei file descriptor. Per
+quest'ultimo si usa la macro \code{max} definita nel nostro file
+\file{macro.h} che raccoglie una collezione di macro di preprocessore di varia
+utilità.
+
+La funzione prosegue poi (\texttt{\small 10--41}) con il ciclo principale, che
+viene ripetuto indefinitamente. Per ogni ciclo si reinizializza
+(\texttt{\small 11--12}) il file descriptor set, impostando i valori per il
+file descriptor associato al socket \var{socket} e per lo standard input (il
+cui valore si recupera con la funzione \func{fileno}). Questo è necessario in
+quanto la successiva (\texttt{\small 13}) chiamata a \func{select} comporta
+una modifica dei due bit relativi, che quindi devono essere reimpostati.
+
+Si noti come la chiamata a \func{select} venga eseguita usando come primo
+argomento il valore di \var{maxfd}, precedentemente calcolato, passando poi il
+solo file descriptor set per il controllo dell'attività in lettura, gli altri
+argomenti sono tutti passati come puntatori nulli non interessando né il
+controllo delle altre attività, né l'impostazione di un valore di timeout.
+
+Al ritorno di \func{select} si provvede a controllare quale dei file
+descriptor presneta attività, si comincia (\texttt{\small 14--24}) con il file
+descriptor associato allo standard input. In caso di attività (quando cioè
+\macro{FD_ISSET} ritorna una valore diverso da zero) si esegue (\texttt{\small
+ 15}) una \func{fgets} per leggere gli eventuali dati presenti; se non ve ne
+sono (e la funzione restituisce pertanto un puntatore nullo) si ritorna
+immediatamente (\texttt{\small 16}) dato che questo significa che si è chiuso
+lo standard input; altrimenti (\texttt{\small 18--22}) si scrivono i dati sul
+socket, uscendo immediatamente in caso di errore di scrittura.
+
+Controllato lo standard input si passa a controllare (\texttt{\small 25--40})
+il socket connesso, in caso di attività si esegue (\texttt{\small 26}) subito
+una \func{read} di cui si controlla il valore di ritorno; se questo è negativo
+(\texttt{\small 27--30}) si è avuto un errore e pertanto si esce
+immediatamente segnalandolo, se è nullo (\texttt{\small 31--34})