+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \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 fig.~\ref{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 fig.~\ref{fig:TCP_ClientEcho_third}, il
+codice completo si trova nel file \file{TCP\_echo\_third.c} dei sorgenti
+allegati alla guida.
+
+In questo caso la funzione comincia (\texttt{\small 8--9}) con l'azzeramento
+del \textit{file descriptor set} \var{fset} e l'impostazione del valore
+\var{maxfd}, da passare a \func{select} come massimo per il numero di file
+descriptor. Per determinare 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 \textit{file descriptor set}, impostando i valori
+per il file descriptor associato al socket \var{socket} e per lo
+\textit{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 relativia
+questi file, che quindi devono essere reimpostati all'inizio di ogni ciclo.
+
+Si noti come la chiamata a \func{select} venga eseguita usando come primo
+argomento il valore di \var{maxfd}, precedentemente calcolato, e passando poi
+il solo \textit{file descriptor set} per il controllo dell'attività in
+lettura, negli altri argomenti vengono passati tutti puntatori nulli, non
+interessando in questo caso 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 due file
+descriptor presenta attività in lettura, cominciando (\texttt{\small 14--24})
+con il file descriptor associato allo \textit{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 \textit{standard input} e quindi concluso l'utilizzo del
+client; altrimenti (\texttt{\small 18--22}) si scrivono i dati appena letti
+sul socket, prevedendo una uscita immediata in caso di errore di scrittura.
+
+Controllato lo \textit{standard input} si passa a controllare (\texttt{\small
+ 25--40}) il socket connesso, in caso di attività (\texttt{\small 26}) si
+esegue subito una \func{read} di cui si controlla il valore di ritorno; se
+questo è negativo si è avuto un errore e pertanto si esce immediatamente
+segnalandolo (\texttt{\small 27--30}), se è nullo significa che il server ha
+chiuso la connessione, e di nuovo si esce con stampando prima un messaggio di
+avviso (\texttt{\small 31--34}), altrimenti (\texttt{\small 35--39}) si
+effettua la terminazione della stringa e la si stampa a sullo \textit{standard
+ output}, uscendo in caso di errore, per ripetere il ciclo da capo.
+
+Con questo meccanismo il programma invece di essere bloccato in lettura sullo
+\textit{standard input} resta bloccato sulla \func{select}, che ritorna
+soltanto quando viene rilevata attività su uno dei due file descriptor posti
+sotto controllo. Questo di norma avviene solo quando si è scritto qualcosa
+sullo \textit{standard input}, o quando si riceve dal socket la risposta a quanto si
+era appena scritto.
+
+Ma adesso il client diventa capace di accorgersi immediatamente della
+terminazione del server; in tal caso infatti il server chiuderà il socket
+connesso, ed alla ricezione del FIN la funzione \func{select} ritornerà (come
+illustrato in sez.~\ref{sec:TCP_sock_select}) segnalando una condizione di end
+of file, per cui il nostro client potrà uscire immediatamente.
+
+Riprendiamo la situazione affrontata in sez.~\ref{sec:TCP_server_crash},
+terminando il server durante una connessione, in questo caso quello che
+otterremo, una volta scritta una prima riga ed interrotto il server con un
+\texttt{C-c}, sarà:
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./echo 192.168.1.1}
+Prima riga
+Prima riga
+EOF sul socket
+\end{Console}
+%$
+dove l'ultima riga compare immediatamente dopo aver interrotto il server. Il
+nostro client infatti è in grado di accorgersi immediatamente che il socket
+connesso è stato chiuso ed uscire immediatamente.
+
+Veniamo allora agli altri scenari di terminazione anomala visti in
+sez.~\ref{sec:TCP_conn_crash}. Il primo di questi è l'interruzione fisica della
+connessione; in questo caso avremo un comportamento analogo al precedente, in
+cui si scrive una riga e non si riceve risposta dal server e non succede
+niente fino a quando non si riceve un errore di \errcode{EHOSTUNREACH} o
+\errcode{ETIMEDOUT} a seconda dei casi.
+
+La differenza è che stavolta potremo scrivere più righe dopo l'interruzione,
+in quanto il nostro client dopo aver inviato i dati non si bloccherà più nella
+lettura dal socket, ma nella \func{select}; per questo potrà accettare
+ulteriore dati che scriverà di nuovo sul socket, fintanto che c'è spazio sul
+buffer di uscita (ecceduto il quale si bloccherà in scrittura).
+
+Si ricordi infatti che il client non ha modo di determinare se la connessione
+è attiva o meno (dato che in molte situazioni reali l'inattività può essere
+temporanea). Tra l'altro se si ricollega la rete prima della scadenza del
+timeout, potremo anche verificare come tutto quello che si era scritto viene
+poi effettivamente trasmesso non appena la connessione ridiventa attiva, per
+cui otterremo qualcosa del tipo:
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./echo 192.168.1.1}
+Prima riga
+Prima riga
+Seconda riga dopo l'interruzione
+Terza riga
+Quarta riga
+Seconda riga dopo l'interruzione
+Terza riga
+Quarta riga
+\end{Console}
+%$
+in cui, una volta riconnessa la rete, tutto quello che abbiamo scritto durante
+il periodo di disconnessione restituito indietro e stampato immediatamente.
+
+Lo stesso comportamento visto in sez.~\ref{sec:TCP_server_crash} si riottiene
+nel caso di un crollo completo della macchina su cui sta il server. In questo
+caso di nuovo il client non è in grado di accorgersi di niente dato che si
+suppone che il programma server non venga terminato correttamente, ma si
+blocchi tutto senza la possibilità di avere l'emissione di un segmento FIN che
+segnala la terminazione della connessione.
+
+Di nuovo fintanto che la connessione non si riattiva (con il riavvio della
+macchina del server) il client non è in grado di fare altro che accettare
+dell'input e tentare di inviarlo. La differenza in questo caso è che non
+appena la connessione ridiventa attiva i dati verranno sì trasmessi, ma
+essendo state perse tutte le informazioni relative alle precedenti connessioni
+ai tentativi di scrittura del client sarà risposto con un segmento RST che
+provocherà il ritorno di \func{select} per la ricezione di un errore di
+\errcode{ECONNRESET}.
+
+
+\subsection{La funzione \func{shutdown}}
+\label{sec:TCP_shutdown}
+
+Come spiegato in sez.~\ref{sec:TCP_conn_term} il procedimento di chiusura di
+un socket TCP prevede che da entrambe le parti venga emesso un segmento FIN. È
+pertanto del tutto normale dal punto di vista del protocollo che uno dei due
+capi chiuda la connessione quando l'altro capo la lascia aperta; abbiamo
+incontrato questa situazione nei vari scenari critici di
+sez.~\ref{sec:TCP_echo_critical}.
+
+\itindbeg{half-close}
+
+È pertanto possibile avere una situazione in cui un capo della connessione,
+non avendo più nulla da scrivere, possa chiudere il socket, segnalando così
+l'avvenuta terminazione della trasmissione (l'altro capo riceverà infatti un
+\textit{end-of-file} in lettura) mentre dall'altra parte si potrà proseguire
+la trasmissione dei dati scrivendo sul socket che da quel lato è ancora
+aperto. Questa è quella situazione in cui si dice che il socket è
+\textsl{mezzo chiuso} (``\textit{half closed}'').
+
+Il problema che si pone è che se la chiusura del socket è effettuata con la
+funzione \func{close}, come spiegato in sez.~\ref{sec:TCP_func_close}, si
+perde ogni possibilità di poter leggere quanto l'altro capo può star
+continuando a scrivere. Per permettere di segnalare che si è finito con la
+scrittura, continuando al contempo a leggere quanto può provenire dall'altro
+capo del socket, si può usare la funzione \funcd{shutdown}, il cui prototipo
+è:
+
+\begin{funcproto}{
+\fhead{sys/socket.h}
+\fdecl{int shutdown(int sockfd, int how)}
+\fdesc{Chiude un lato della connessione fra due socket.}
+}
+
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+ caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EBADF}] \param{sockfd} non è un file descriptor valido.
+ \item[\errcode{EINVAL}] il valore di \param{how} non è valido.
+ \item[\errcode{ENOTCONN}] il socket non è connesso.
+ \item[\errcode{ENOTSOCK}] il file descriptor non corrisponde a un socket.
+ \end{errlist}}
+\end{funcproto}
+
+La funzione prende come primo argomento il socket \param{sockfd} su cui si
+vuole operare e come secondo argomento un valore intero \param{how} che indica
+la modalità di chiusura del socket, quest'ultima può prendere soltanto tre
+valori:
+\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}}
+\item[\constd{SHUT\_RD}] chiude il lato in lettura del socket, non sarà più
+ possibile leggere dati da esso, tutti gli eventuali dati trasmessi
+ dall'altro capo del socket saranno automaticamente scartati dal kernel, che,
+ in caso di socket TCP, provvederà comunque ad inviare i relativi segmenti di
+ ACK.
+\item[\constd{SHUT\_WR}] chiude il lato in scrittura del socket, non sarà più
+ possibile scrivere dati su di esso. Nel caso di socket TCP la chiamata causa
+ l'emissione di un segmento FIN, secondo la procedura chiamata
+ \textit{half-close}. Tutti i dati presenti nel buffer di scrittura prima
+ della chiamata saranno inviati, seguiti dalla sequenza di chiusura
+ illustrata in sez.~\ref{sec:TCP_conn_term}.
+\item[\constd{SHUT\_RDWR}] chiude sia il lato in lettura che quello in
+ scrittura del socket. È equivalente alla chiamata in sequenza con
+ \const{SHUT\_RD} e \const{SHUT\_WR}.
+\end{basedescript}
+
+\itindend{half-close}
+
+Ci si può chiedere quale sia l'utilità di avere introdotto \const{SHUT\_RDWR}
+quando questa sembra rendere \func{shutdown} del tutto equivalente ad una
+\func{close}. In realtà non è così, esiste infatti un'altra differenza con
+\func{close}, più sottile. Finora infatti non ci siamo presi la briga di
+sottolineare in maniera esplicita che, come per i file e le \textit{fifo},
+anche per i socket possono esserci più riferimenti contemporanei ad uno stesso
+socket.
+
+Per cui si avrebbe potuto avere l'impressione che sia una corrispondenza
+univoca fra un socket ed il file descriptor con cui vi si accede. Questo non è
+assolutamente vero, (e lo abbiamo già visto nel codice del server di
+fig.~\ref{fig:TCP_echo_server_first_code}), ed è invece assolutamente normale
+che, come per gli altri oggetti, ci possano essere più file descriptor che
+fanno riferimento allo stesso socket.
+
+Allora se avviene uno di questi casi quello che succederà è che la chiamata a
+\func{close} darà effettivamente avvio alla sequenza di chiusura di un socket
+soltanto quando il numero di riferimenti a quest'ultimo diventerà nullo.
+Fintanto che ci sono file descriptor che fanno riferimento ad un socket l'uso
+di \func{close} si limiterà a deallocare nel processo corrente il file
+descriptor utilizzato, ma il socket resterà pienamente accessibile attraverso
+tutti gli altri riferimenti.
+
+Se torniamo all'esempio originale del server di
+fig.~\ref{fig:TCP_echo_server_first_code} abbiamo infatti che ci sono due
+\func{close}, una sul socket connesso nel padre, ed una sul socket in ascolto
+nel figlio, ma queste non effettuano nessuna chiusura reale di detti socket,
+dato che restano altri riferimenti attivi, uno al socket connesso nel figlio
+ed uno a quello in ascolto nel padre.
+
+Questo non avviene affatto se si usa \func{shutdown} con argomento
+\const{SHUT\_RDWR} al posto di \func{close}; in questo caso infatti la
+chiusura del socket viene effettuata immediatamente, indipendentemente dalla
+presenza di altri riferimenti attivi, e pertanto sarà efficace anche per tutti
+gli altri file descriptor con cui, nello stesso o in altri processi, si fa
+riferimento allo stesso socket.
+
+Il caso più comune di uso di \func{shutdown} è comunque quello della chiusura
+del lato in scrittura, per segnalare all'altro capo della connessione che si è
+concluso l'invio dei dati, restando comunque in grado di ricevere quanto
+questi potrà ancora inviarci. Questo è ad esempio l'uso che ci serve per
+rendere finalmente completo il nostro esempio sul servizio \textit{echo}.
+
+Il nostro client infatti presenta ancora un problema, che nell'uso che finora
+ne abbiamo fatto non è emerso, ma che ci aspetta dietro l'angolo non appena
+usciamo dall'uso interattivo e proviamo ad eseguirlo redirigendo
+\textit{standard input} e \textit{standard output}. Così se eseguiamo:
+\begin{Console}
+[piccardi@gont sources]$ \textbf{./echo 192.168.1.1 < ../fileadv.tex > copia}
+\end{Console}
+%$
+vedremo che il file \texttt{copia} risulta mancare della parte finale.
+
+Per capire cosa avviene in questo caso occorre tenere presente come avviene la
+comunicazione via rete; quando redirigiamo lo \textit{standard input} il
+nostro client inizierà a leggere il contenuto del file \texttt{../fileadv.tex}
+a blocchi di dimensione massima pari a \texttt{MAXLINE} per poi scriverlo,
+alla massima velocità consentitagli dalla rete, sul socket. Dato che la
+connessione è con una macchina remota, occorre un certo tempo perché i
+pacchetti vi arrivino, vengano processati, e poi tornino
+indietro. Considerando trascurabile il tempo di processo, questo tempo è
+quello impiegato nella trasmissione via rete, che viene detto RTT (dalla
+denominazione inglese \itindex{Round~Trip~Time~(RTT)} \textit{Round Trip
+ Time}) ed è quello che viene stimato con l'uso del comando \cmd{ping}.
+
+A questo punto, se torniamo al codice mostrato in
+fig.~\ref{fig:TCP_ClientEcho_third}, possiamo vedere che mentre i pacchetti
+sono in transito sulla rete il client continua a leggere e a scrivere fintanto
+che il file in ingresso finisce. Però non appena viene ricevuto un
+\textit{end-of-file} in ingresso il nostro client termina. Nel caso
+interattivo, in cui si inviavano brevi stringhe una alla volta, c'era sempre
+il tempo di eseguire la lettura completa di quanto il server rimandava
+indietro. In questo caso invece, quando il client termina, essendo la
+comunicazione saturata e a piena velocità, ci saranno ancora pacchetti in
+transito sulla rete che devono arrivare al server e poi tornare indietro, ma
+siccome il client esce immediatamente dopo la fine del file in ingresso,
+questi non faranno a tempo a completare il percorso e verranno persi.
+
+Per evitare questo tipo di problema, invece di uscire una volta completata la
+lettura del file in ingresso, occorre usare \func{shutdown} per effettuare la
+chiusura del lato in scrittura del socket. In questo modo il client segnalerà
+al server la chiusura del flusso dei dati, ma potrà continuare a leggere
+quanto il server gli sta ancora inviando indietro, fino a quando anch'esso,
+riconosciuta la chiusura del socket in scrittura da parte del client,
+effettuerà la chiusura dalla sua parte. Solo alla ricezione della chiusura del
+socket da parte del server il client potrà essere sicuro della ricezione di
+tutti i dati e della terminazione effettiva della connessione.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/ClientEcho.c}
+ \end{minipage}
+ \normalsize
+ \caption{La sezione nel codice della versione finale della funzione
+ \func{ClientEcho}, che usa \func{shutdown} per una conclusione corretta
+ della connessione.}
+ \label{fig:TCP_ClientEcho}
+\end{figure}
+
+Si è allora riportato in fig.~\ref{fig:TCP_ClientEcho} la versione finale
+della nostra funzione \func{ClientEcho}, in grado di gestire correttamente
+l'intero flusso di dati fra client e server. Il codice completo del client,
+comprendente la gestione delle opzioni a riga di comando e le istruzioni per
+la creazione della connessione, si trova nel file
+\texttt{TCP\_echo\_fourth.c}, distribuito coi sorgenti allegati alla guida.
+
+La nuova versione è molto simile alla precedente di
+fig.~\ref{fig:TCP_ClientEcho_third}; la prima differenza è l'introduzione
+(\texttt{\small 7}) della variabile \var{eof}, inizializzata ad un valore
+nullo, che serve a mantenere traccia dell'avvenuta conclusione della lettura
+del file in ingresso.
+
+La seconda modifica (\texttt{\small 12--15}) è stata quella di rendere
+subordinata ad un valore nullo di \var{eof} l'impostazione del file descriptor
+set per l'osservazione dello \textit{standard input}. Se infatti il valore di
+\var{eof} è non nullo significa che si è già raggiunta la fine del file in
+ingresso ed è pertanto inutile continuare a tenere sotto controllo lo
+\textit{standard input} nella successiva (\texttt{\small 16}) chiamata a
+\func{select}.
+
+Le maggiori modifiche rispetto alla precedente versione sono invece nella
+gestione (\texttt{\small 18--22}) del caso in cui la lettura con \func{fgets}
+restituisce un valore nullo, indice della fine del file. Questa nella
+precedente versione causava l'immediato ritorno della funzione; in questo caso
+prima (\texttt{\small 19}) si imposta opportunamente \var{eof} ad un valore
+non nullo, dopo di che (\texttt{\small 20}) si effettua la chiusura del lato
+in scrittura del socket con \func{shutdown}. Infine (\texttt{\small 21}) si
+usa la macro \macro{FD\_CLR} per togliere lo \textit{standard input} dal
+\textit{file descriptor set}.
+
+In questo modo anche se la lettura del file in ingresso è conclusa, la
+funzione non esce dal ciclo principale (\texttt{\small 11--50}), ma continua
+ad eseguirlo ripetendo la chiamata a \func{select} per tenere sotto controllo
+soltanto il socket connesso, dal quale possono arrivare altri dati, che
+saranno letti (\texttt{\small 31}) ed opportunamente trascritti
+(\texttt{\small 44--48}) sullo \textit{standard output}.
+
+Il ritorno della funzione, e la conseguente terminazione normale del client,
+viene invece adesso gestito all'interno (\texttt{\small 30--49}) della lettura
+dei dati dal socket; se infatti dalla lettura del socket si riceve una
+condizione di \textit{end-of-file}, la si tratterà (\texttt{\small 36--43}) in
+maniera diversa a seconda del valore di \var{eof}. Se infatti questa è diversa
+da zero (\texttt{\small 37--39}), essendo stata completata la lettura del file
+in ingresso, vorrà dire che anche il server ha concluso la trasmissione dei
+dati restanti, e si potrà uscire senza errori, altrimenti si stamperà
+(\texttt{\small 40--42}) un messaggio di errore per la chiusura precoce della
+connessione.
+
+
+\subsection{Un server basato sull'\textit{I/O multiplexing}}
+\label{sec:TCP_serv_select}
+
+Seguendo di nuovo le orme di Stevens in \cite{UNP1} vediamo ora come con
+l'utilizzo dell'\textit{I/O multiplexing} diventi possibile riscrivere
+completamente il nostro server \textit{echo} con una architettura
+completamente diversa, in modo da evitare di dover creare un nuovo processo
+tutte le volte che si ha una connessione.\footnote{ne faremo comunque una
+ realizzazione diversa rispetto a quella presentata da Stevens in
+ \cite{UNP1}.}
+
+La struttura del nuovo server è illustrata in
+fig.~\ref{fig:TCP_echo_multiplex}, in questo caso avremo un solo processo che
+ad ogni nuova connessione da parte di un client sul socket in ascolto si
+limiterà a registrare l'entrata in uso di un nuovo file descriptor ed
+utilizzerà \func{select} per rilevare la presenza di dati in arrivo su tutti i
+file descriptor attivi, operando direttamente su ciascuno di essi.
+
+\begin{figure}[!htb]
+ \centering \includegraphics[width=13cm]{img/TCPechoMult}
+ \caption{Schema del nuovo server echo basato sull'\textit{I/O multiplexing}.}
+ \label{fig:TCP_echo_multiplex}
+\end{figure}
+
+La sezione principale del codice del nuovo server è illustrata in
+fig.~\ref{fig:TCP_SelectEchod}. Si è tralasciata al solito la gestione delle
+opzioni, che è identica alla versione precedente. Resta invariata anche tutta
+la parte relativa alla gestione dei segnali, degli errori, e della cessione
+dei privilegi, così come è identica la gestione della creazione del socket (si
+può fare riferimento al codice già illustrato in
+sez.~\ref{sec:TCPsimp_server_main}); al solito il codice completo del server è
+disponibile coi sorgenti allegati nel file \texttt{select\_echod.c}.
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/select_echod.c}
+ \end{minipage}
+ \normalsize
+ \caption{La sezione principale della nuova versione di server
+ \textit{echo} basato sull'uso della funzione \func{select}.}
+ \label{fig:TCP_SelectEchod}
+\end{figure}
+
+In questo caso, una volta aperto e messo in ascolto il socket, tutto quello
+che ci servirà sarà chiamare \func{select} per rilevare la presenza di nuove
+connessioni o di dati in arrivo, e processarli immediatamente. Per realizzare
+lo schema mostrato in fig.~\ref{fig:TCP_echo_multiplex} il programma usa una
+tabella dei socket connessi mantenuta nel vettore \var{fd\_open} dimensionato
+al valore di \const{FD\_SETSIZE}, ed una variabile \var{max\_fd} per
+registrare il valore più alto dei file descriptor aperti.
+
+Prima di entrare nel ciclo principale (\texttt{\small 5--53}) la nostra
+tabella viene inizializzata (\texttt{\small 2}) a zero (valore che
+utilizzeremo come indicazione del fatto che il relativo file descriptor non è
+aperto), mentre il valore massimo (\texttt{\small 3}) per i file descriptor
+aperti viene impostato a quello del socket in ascolto, in quanto esso è
+l'unico file aperto, oltre i tre standard, e pertanto avrà il valore più alto,
+che verrà anche (\texttt{\small 4}) inserito nella tabella.
+
+La prima sezione (\texttt{\small 6--8}) del ciclo principale esegue la
+costruzione del \textit{file descriptor set} \var{fset} in base ai socket
+connessi in un certo momento; all'inizio ci sarà soltanto il socket in ascolto
+ma nel prosieguo delle operazioni verranno utilizzati anche tutti i socket
+connessi registrati nella tabella \var{fd\_open}. Dato che la chiamata di
+\func{select} modifica il valore del \textit{file descriptor set} è necessario
+ripetere (\texttt{\small 6}) ogni volta il suo azzeramento per poi procedere
+con il ciclo (\texttt{\small 7--8}) in cui si impostano i socket trovati
+attivi.
+
+Per far questo si usa la caratteristica dei file descriptor, descritta in
+sez.~\ref{sec:file_open_close}, per cui il kernel associa sempre ad ogni nuovo
+file il file descriptor con il valore più basso disponibile. Questo fa sì che
+si possa eseguire il ciclo (\texttt{\small 7}) a partire da un valore minimo,
+che sarà sempre quello del socket in ascolto, mantenuto in \var{list\_fd},
+fino al valore massimo di \var{max\_fd} che dovremo aver cura di tenere
+aggiornato. Dopo di che basterà controllare (\texttt{\small 8}) nella nostra
+tabella se il file descriptor è in uso o meno,\footnote{si tenga presente che
+ benché il kernel assegni sempre il primo valore libero, si potranno sempre
+ avere dei \textsl{buchi} nella nostra tabella dato che nelle operazioni i
+ socket saranno aperti e chiusi in corrispondenza della creazione e
+ conclusione delle connessioni.} e impostare \var{fset} di conseguenza.
+
+Una volta inizializzato con i socket aperti il nostro \textit{file descriptor
+ set} potremo chiamare \func{select} per fargli osservare lo stato degli
+stessi (in lettura, presumendo che la scrittura sia sempre consentita). Come
+per il precedente esempio di sez.~\ref{sec:TCP_child_hand}, essendo questa
+l'unica funzione che può bloccarsi ed essere interrotta da un segnale, la
+eseguiremo (\texttt{\small 9--10}) all'interno di un ciclo di \code{while},
+che la ripete indefinitamente qualora esca con un errore di \errcode{EINTR}.
+Nel caso invece di un errore normale si provvede (\texttt{\small 11--14}) ad
+uscire dal programma stampando un messaggio di errore.
+
+Infine quando la funzione ritorna normalmente avremo in \var{n} il numero di
+socket da controllare. Nello specifico si danno due casi per cui \func{select}
+può ritornare: o si è ricevuta una nuova connessione ed è pronto il socket in
+ascolto, sul quale si può eseguire \func{accept}, o c'è attività su uno dei
+socket connessi, sui quali si può eseguire \func{read}.
+
+Il primo caso viene trattato immediatamente (\texttt{\small 15--24}): si
+controlla (\texttt{\small 15}) che il socket in ascolto sia fra quelli attivi,
+nel qual caso anzitutto (\texttt{\small 16}) se ne decrementa il numero
+mantenuto nella variabile \var{n}. Poi, inizializzata (\texttt{\small 17}) la
+lunghezza della struttura degli indirizzi, si esegue \func{accept} per
+ottenere il nuovo socket connesso, controllando che non ci siano errori
+(\texttt{\small 18--21}). In questo caso non c'è più la necessità di
+controllare per interruzioni dovute a segnali, in quanto siamo sicuri che
+\func{accept} non si bloccherà. Per completare la trattazione occorre a questo
+punto aggiungere (\texttt{\small 22}) il nuovo file descriptor alla tabella di
+quelli connessi, ed inoltre, se è il caso, aggiornare (\texttt{\small 23}) il
+valore massimo in \var{max\_fd}.
+
+Una volta controllato l'arrivo di nuove connessioni si passa a verificare se
+ci sono dati sui socket connessi, per questo si ripete un ciclo
+(\texttt{\small 26--52}) fintanto che il numero di socket attivi indicato
+dalla variabile \var{n} resta diverso da zero. In questo modo, se l'unico
+socket con attività era quello connesso, avendola opportunamente decrementata
+in precedenza, essa risulterà nulla, pertanto il ciclo di verifica verrà
+saltato e si ritornerà all'inzizio del ciclo principale, ripetendo, dopo
+l'inizializzazione del \textit{file descriptor set} con i nuovi valori nella
+tabella, la chiamata di \func{select}.
+
+Se il socket attivo non è quello in ascolto, o ce ne sono comunque anche
+altri, il valore di \var{n} non sarà nullo ed il controllo sarà
+eseguito. Prima di entrare nel ciclo di veridica comunque si inizializza
+(\texttt{\small 25}) il valore della variabile \var{i}, che useremo come
+indice nella tabella \var{fd\_open}, al valore minimo, corrispondente al file
+descriptor del socket in ascolto.
+
+Il primo passo (\texttt{\small 27}) nella verifica è incrementare il valore
+dell'indice \var{i} per posizionarsi sul primo valore possibile per un file
+descriptor associato ad un eventuale socket connesso, dopo di che si controlla
+(\texttt{\small 28}) se questo è nella tabella dei socket connessi, chiedendo
+la ripetizione del ciclo in caso contrario. Altrimenti si passa a verificare
+(\texttt{\small 29}) se il file descriptor corrisponde ad uno di quelli
+attivi, e nel caso si esegue (\texttt{\small 30}) una lettura, uscendo con un
+messaggio in caso di errore (\texttt{\small 31--35}).
+
+Se (\texttt{\small 36}) il numero di byte letti \var{nread} è nullo si è in
+presenza di una \textit{end-of-file}, indice che una connessione che si è
+chiusa, che deve essere trattata (\texttt{\small 36--45}) opportunamente. Il
+primo passo è chiudere (\texttt{\small 37}) anche il proprio capo del socket e
+rimuovere (\texttt{\small 38}) il file descriptor dalla tabella di quelli
+aperti, inoltre occorre verificare (\texttt{\small 39}) se il file descriptor
+chiuso è quello con il valore più alto, nel qual caso occorre trovare
+(\texttt{\small 39--43}) il nuovo massimo, altrimenti (\texttt{\small 44}) si
+può ripetere il ciclo da capo per esaminare (se ne restano) ulteriori file
+descriptor attivi.
+
+Se però è stato chiuso il file descriptor più alto, dato che la scansione dei
+file descriptor attivi viene fatta a partire dal valore più basso, questo
+significa che siamo anche arrivati alla fine della scansione, per questo
+possiamo utilizzare direttamente il valore dell'indice \var{i} con un ciclo
+all'indietro (\texttt{\small 40}) che trova il primo valore per cui la tabella
+presenta un file descriptor aperto, e lo imposta (\texttt{\small 41}) come
+nuovo massimo, per poi tornare (\texttt{\small 42}) al ciclo principale con un
+\code{break}, e rieseguire \func{select}.
+
+Se infine si sono effettivamente letti dei dati dal socket (ultimo caso
+rimasto) si potrà invocare immediatamente (\texttt{\small 46})
+\func{FullWrite} per riscriverli indietro sul socket stesso, avendo cura di
+uscire con un messaggio in caso di errore (\texttt{\small 47--50}). Si noti
+che nel ciclo si esegue una sola lettura, contrariamente a quanto fatto con la
+precedente versione (si riveda il codice di fig.~\ref{fig:TCP_ServEcho_second})
+in cui si continuava a leggere fintanto che non si riceveva un
+\textit{end-of-file}, questo perché usando l'\textit{I/O multiplexing} non si
+vuole essere bloccati in lettura.
+
+L'uso di \func{select} ci permette di trattare automaticamente anche il caso
+in cui la \func{read} non è stata in grado di leggere tutti i dati presenti
+sul socket, dato che alla iterazione successiva \func{select} ritornerà
+immediatamente segnalando l'ulteriore disponibilità.
+
+Il nostro server comunque soffre di una vulnerabilità per un attacco di tipo
+\textit{Denial of Service}. Il problema è che in caso di blocco di una
+qualunque delle funzioni di I/O, non avendo usato processi separati, tutto il
+server si ferma e non risponde più a nessuna richiesta. Abbiamo scongiurato
+questa evenienza per l'I/O in ingresso con l'uso di \func{select}, ma non vale
+altrettanto per l'I/O in uscita. Il problema pertanto può sorgere qualora una
+delle chiamate a \func{write} effettuate da \func{FullWrite} si blocchi.
+
+Con il funzionamento normale questo non accade in quanto il server si limita a
+scrivere quanto riceve in ingresso, ma qualora venga utilizzato un client
+malevolo che esegua solo scritture e non legga mai indietro l'\textsl{eco} del
+server, si potrebbe giungere alla saturazione del buffer di scrittura, ed al
+conseguente blocco del server su di una \func{write}.
+
+Le possibili soluzioni in questo caso sono quelle di ritornare ad eseguire il
+ciclo di risposta alle richieste all'interno di processi separati, utilizzare
+un timeout per le operazioni di scrittura, o eseguire queste ultime in
+modalità non bloccante, concludendo le operazioni qualora non vadano a buon
+fine.
+
+
+\subsection{\textit{I/O multiplexing} con \func{poll}}
+\label{sec:TCP_serv_poll}
+
+Finora abbiamo trattato le problematiche risolubili con l'\textit{I/O
+ multiplexing} impiegando la funzione \func{select}. Questo è quello che
+avviene nella maggior parte dei casi, in quanto essa è nata sotto BSD proprio
+per affrontare queste problematiche con i socket. Abbiamo però visto in
+sez.~\ref{sec:file_multiplexing} come la funzione \func{poll} possa costituire
+una alternativa a \func{select}, con alcuni vantaggi, non soffrendo delle
+limitazioni dovute all'uso dei \textit{file descriptor set}.
+
+Ancora una volta in sez.~\ref{sec:file_poll} abbiamo trattato la funzione in
+maniera generica, parlando di file descriptor, ma come per \func{select}
+quando si ha a che fare con dei socket, il concetto di essere \textsl{pronti}
+per l'I/O deve essere specificato nei dettagli per tener conto delle
+condizioni della rete. Inoltre deve essere specificato come viene classificato
+il traffico nella suddivisione fra dati normali e prioritari. In generale
+pertanto:
+\begin{itemize}
+\item i dati inviati su un socket vengono considerati traffico normale,
+ pertanto vengono rilevati alla loro ricezione sull'altro capo da una
+ selezione effettuata con \const{POLLIN} o \const{POLLRDNORM};
+\item i dati urgenti \textit{out-of-band} (vedi
+ sez.~\ref{sec:TCP_urgent_data}) su un socket TCP vengono considerati
+ traffico prioritario e vengono rilevati da una condizione \const{POLLIN},
+ \const{POLLPRI} o \const{POLLRDBAND}.
+\item la chiusura di una connessione (cioè la ricezione di un segmento FIN)
+ viene considerato traffico normale, pertanto viene rilevato da una
+ condizione \const{POLLIN} o \const{POLLRDNORM}, ma una conseguente chiamata
+ a \func{read} restituirà 0.
+\item la disponibilità di spazio sul socket per la scrittura di dati viene
+ segnalata con una condizione \const{POLLOUT}.
+\item quando uno dei due capi del socket chiude un suo lato della connessione
+ con \func{shutdown} si riceve una condizione di \const{POLLHUP}.
+\item la presenza di un errore sul socket (sia dovuta ad un segmento RST che a
+ timeout) viene considerata traffico normale, ma viene segnalata anche dalla
+ condizione \const{POLLERR}.
+\item la presenza di una nuova connessione su un socket in ascolto può essere
+ considerata sia traffico normale che prioritario, nel caso di Linux la
+ realizzazione dello \textit{stack TCP} la classifica come normale.
+\end{itemize}
+
+Come esempio dell'uso di \func{poll} proviamo allora a riscrivere il server
+\textit{echo} secondo lo schema di fig.~\ref{fig:TCP_echo_multiplex} usando
+\func{poll} al posto di \func{select}. In questo caso dovremo fare qualche
+modifica, per tenere conto della diversa sintassi delle due funzioni, ma la
+struttura del programma resta sostanzialmente la stessa.
+
+
+\begin{figure}[!htbp]
+ \footnotesize \centering
+ \begin{minipage}[c]{\codesamplewidth}
+ \includecodesample{listati/poll_echod.c}
+ \end{minipage}
+ \normalsize
+ \caption{La sezione principale della nuova versione di server
+ \textit{echo} basato sull'uso della funzione \func{poll}.}
+ \label{fig:TCP_PollEchod}
+\end{figure}
+
+In fig.~\ref{fig:TCP_PollEchod} è riportata la sezione principale della nuova
+versione del server, la versione completa del codice è riportata nel file
+\texttt{poll\_echod.c} dei sorgenti allegati alla guida. Al solito nella
+figura si sono tralasciate la gestione delle opzioni, la creazione del socket
+in ascolto, la cessione dei privilegi e le operazioni necessarie a far
+funzionare il programma come demone, privilegiando la sezione principale del
+programma.
+
+Come per il precedente server basato su \func{select} il primo passo
+(\texttt{\small 2--8}) è quello di inizializzare le variabili necessarie. Dato
+che in questo caso dovremo usare un vettore di strutture occorre anzitutto
+(\texttt{\small 2}) allocare la memoria necessaria utilizzando il numero
+massimo \var{n} di socket osservabili, che viene impostato attraverso
+l'opzione \texttt{-n} ed ha un valore di default di 256.
+
+Dopo di che si preimposta (\texttt{\small 3}) il valore \var{max\_fd} del file
+descriptor aperto con valore più alto a quello del socket in ascolto (al
+momento l'unico), e si provvede (\texttt{\small 4--7}) ad inizializzare le
+strutture, disabilitando l'osservazione (\texttt{\small 5}) con un valore
+negativo del campo \var{fd}, ma predisponendo (\texttt{\small 6}) il campo
+\var{events} per l'osservazione dei dati normali con \const{POLLRDNORM}.
+Infine (\texttt{\small 8}) si attiva l'osservazione del socket in ascolto
+inizializzando la corrispondente struttura. Questo metodo comporta, in
+modalità interattiva, lo spreco di tre strutture (quelle relative a
+\textit{standard input}, \textit{standard output} e \textit{standard error})
+che non vengono mai utilizzate in quanto la prima è sempre quella relativa al
+socket in ascolto.
+
+Una volta completata l'inizializzazione tutto il lavoro viene svolto
+all'interno del ciclo principale \texttt{\small 9--53}) che ha una struttura
+sostanzialmente identica a quello usato per il precedente esempio basato su
+\func{select}. La prima istruzione (\texttt{\small 10}) è quella di eseguire
+\func{poll} all'interno di un ciclo che la ripete qualora venisse interrotta
+da un segnale, da cui si esce soltanto quando la funzione ritorna restituendo
+nella variabile \var{n} il numero di file descriptor trovati attivi. Qualora
+invece si sia ottenuto un errore si procede (\texttt{\small 11--14}) alla
+terminazione immediata del processo provvedendo a stampare una descrizione
+dello stesso.
+
+Una volta ottenuta dell'attività su un file descriptor si hanno di nuovo due
+possibilità. La prima è che ci sia attività sul socket in ascolto, indice di
+una nuova connessione, nel qual caso si controlla (\texttt{\small 17}) se il
+campo \var{revents} della relativa struttura è attivo; se è così si provvede
+(\texttt{\small 16}) a decrementare la variabile \var{n} (che assume il
+significato di numero di file descriptor attivi rimasti da controllare) per
+poi (\texttt{\small 17--21}) effettuare la chiamata ad \func{accept},
+terminando il processo in caso di errore. Se la chiamata ad \func{accept} ha
+successo si procede attivando (\texttt{\small 22}) la struttura relativa al
+nuovo file descriptor da essa ottenuto, modificando (\texttt{\small 23})
+infine quando necessario il valore massimo dei file descriptor aperti
+mantenuto in \var{max\_fd}.
+
+La seconda possibilità è che vi sia dell'attività su uno dei socket aperti in
+precedenza, nel qual caso si inizializza (\texttt{\small 25}) l'indice \var{i}
+del vettore delle strutture \struct{pollfd} al valore del socket in ascolto,
+dato che gli ulteriori socket aperti avranno comunque un valore superiore. Il
+ciclo (\texttt{\small 26--52}) prosegue fintanto che il numero di file
+descriptor attivi, mantenuto nella variabile \var{n}, è diverso da zero. Se
+pertanto ci sono ancora socket attivi da individuare si comincia con
+l'incrementare (\texttt{\small 27}) l'indice e controllare (\texttt{\small
+ 28}) se corrisponde ad un file descriptor in uso analizzando il valore del
+campo \var{fd} della relativa struttura e chiudendo immediatamente il ciclo
+qualora non lo sia. Se invece il file descriptor è in uso si verifica
+(\texttt{\small 29}) se c'è stata attività controllando il campo
+\var{revents}.
+
+Di nuovo se non si verifica la presenza di attività il ciclo si chiude subito,
+altrimenti si provvederà (\texttt{\small 30}) a decrementare il numero \var{n}
+di file descriptor attivi da controllare e ad eseguire (\texttt{\small 31}) la
+lettura, ed in caso di errore (\texttt{\small 32--35}) al solito lo si
+notificherà uscendo immediatamente. Qualora invece si ottenga una condizione
+di \textit{end-of-file} (\texttt{\small 36--45}) si provvederà a chiudere
+(\texttt{\small 37}) anche il nostro capo del socket e a marcarlo
+(\texttt{\small 38}) come inutilizzato nella struttura ad esso associata.
+Infine dovrà essere ricalcolato (\texttt{\small 39--43}) un eventuale nuovo
+valore di \var{max\_fd}. L'ultimo passo è chiudere (\texttt{\small 44}) il
+ciclo in quanto in questo caso non c'è più niente da riscrivere all'indietro
+sul socket.
+
+Se invece si sono letti dei dati si provvede (\texttt{\small 46}) ad
+effettuarne la riscrittura all'indietro, con il solito controllo ed eventuale
+uscita e notifica in caso di errore (\texttt{\small 47--51}).
+
+Come si può notare la logica del programma è identica a quella vista in
+fig.~\ref{fig:TCP_SelectEchod} per l'analogo server basato su \func{select};
+la sola differenza significativa è che in questo caso non c'è bisogno di
+rigenerare i \textit{file descriptor set} in quanto l'uscita è indipendente
+dai dati in ingresso. Si applicano comunque anche a questo server le
+considerazioni finali di sez.~\ref{sec:TCP_serv_select}.
+
+
+%\subsection{\textit{I/O multiplexing} con \textit{epoll}}
+%\label{sec:TCP_serv_epoll}
+
+%Da fare.
+
+% TODO fare esempio con epoll
+
+
+
+% LocalWords: socket TCP client dell'I multiplexing stream three way handshake
+% LocalWords: header stack kernel SYN ACK URG syncronize sez bind listen fig
+% LocalWords: accept connect active acknowledge l'acknowledge nell'header MSS
+% LocalWords: sequence number l'acknowledgement dell'header options l'header
+% LocalWords: option MMS segment size MAXSEG window advertised Mbit sec nell'
+% LocalWords: timestamp RFC long fat close of l'end l'ACK half shutdown CLOSED
+% LocalWords: netstat SENT ESTABLISHED WAIT IPv Ethernet piggybacking UDP MSL
+% LocalWords: l'overhead Stevens Lifetime router hop limit TTL to live RST SSH
+% LocalWords: routing dell'MSL l'IP multitasking well known port ephemeral BSD
+% LocalWords: ports dall' IANA Assigned Authority like glibc netinet IPPORT AF
+% LocalWords: RESERVED USERRESERVED rsh rlogin pair socketpair Local Address
+% LocalWords: Foreing DNS caching INADDR ANY multihoming loopback ssh fuser ip
+% LocalWords: lsof SOCK sys int sockfd const struct sockaddr serv addr socklen
+% LocalWords: addrlen errno EBADF descriptor EINVAL ENOTSOCK EACCES EADDRINUSE
+% LocalWords: EADDRNOTAVAIL EFAULT ENOTDIR ENOENT ENOMEM ELOOP ENOSR EROFS RPC
+% LocalWords: portmapper htonl tab endianness BROADCAST broadcast any extern fd
+% LocalWords: ADRR INIT DGRAM SEQPACKET servaddr ECONNREFUSED ETIMEDOUT EAGAIN
+% LocalWords: ENETUNREACH EINPROGRESS EALREADY EAFNOSUPPORT EPERM EISCONN proc
+% LocalWords: sysctl filesystem syn retries reset ICMP backlog EOPNOTSUPP RECV
+% LocalWords: connection queue dell'ACK flood spoofing syncookies SOMAXCONN CR
+% LocalWords: RDM EWOULDBLOCK firewall ENOBUFS EINTR EMFILE ECONNABORTED NULL
+% LocalWords: ESOCKTNOSUPPORT EPROTONOSUPPORT ERESTARTSYS connected listening
+% LocalWords: DECnet read write NONBLOCK fcntl getsockname getpeername name ps
+% LocalWords: namelen namlen ENOTCONN exec inetd POSIX daytime FullRead count
+% LocalWords: BUF FullWrite system call INET perror htons inet pton ctime FTP
+% LocalWords: fputs carriage return line feed superdemone daytimed sleep fork
+% LocalWords: daemon cunc logging list conn sock exit snprintf ntop ntohs echo
+% LocalWords: crash superserver L'RFC first ClientEcho stdin stdout fgets main
+% LocalWords: MAXLINE initd echod ServEcho setgid short nogroup nobody setuid
+% LocalWords: demonize PrintErr syslog wrapper log error root RTT EOF ctrl ack
+% LocalWords: while SIGCHLD Signal RESTART sigaction SignalRestart SigHand win
+% LocalWords: flags select recvfrom debug second compat waiting Nsec ENETDOWN
+% LocalWords: EPROTO ENOPROTOOPT EHOSTDOWN ENONET EHOSTUNREACH LINGER tcpdump
+% LocalWords: ECONNRESET advertising PSH SIGTERM strace SIGPIPE gets tcp ARP
+% LocalWords: cache anarres destination unreachable l'I low watermark RCVLOWAT
+% LocalWords: SNDLOWAT third fset maxfd fileno ISSET closed how SHUT RD WR eof
+% LocalWords: RDWR fifo Trip ping fourth CLR sull'I SETSIZE nread break Denial
+% LocalWords: Service poll POLLIN POLLRDNORM POLLPRI POLLRDBAND POLLOUT events
+% LocalWords: POLLHUP POLLERR revents pollfd Di scaling SYNCNT DoS