Correzioni e miglioramenti tipografici
[gapil.git] / tcpsock.tex
index d74edeebed5c34138f0022e33a7cd70ee84243ef..d6b5a945f216475483d1b44356e1004d708a5aa8 100644 (file)
@@ -2468,12 +2468,13 @@ utilizzando un analizzatore di traffico come \cmd{tcpdump}. Il comando
 permette di selezionare, nel traffico di rete generato su una macchina, i
 pacchetti che interessano, stampando a video (o salvando su disco) il loro
 contenuto. Non staremo qui ad entrare nei dettagli dell'uso del programma, che
-sono spiegati dalla pagina di manuale; per l'uso che vogliamo farne quello che
-ci interessa è, posizionandosi sulla macchina che fa da client, selezionare
-tutti i pacchetti che sono diretti o provengono dalla macchina che fa da
-server. In questo modo (posto che non ci siano altre connessioni col server,
-cosa che avremo cura di evitare) tutti i pacchetti rilevati apparterranno alla
-nostra sessione di interrogazione del servizio. 
+sono spiegati dalla pagina di manuale;\footnote{per una trattazione di base si
+  può consultare sez.~5.2.2 di \cite{SGL}.} per l'uso che vogliamo farne
+quello che ci interessa è, posizionandosi sulla macchina che fa da client,
+selezionare tutti i pacchetti che sono diretti o provengono dalla macchina che
+fa da server. In questo modo (posto che non ci siano altre connessioni col
+server, cosa che avremo cura di evitare) tutti i pacchetti rilevati
+apparterranno alla nostra sessione di interrogazione del servizio.
 
 Il comando \cmd{tcpdump} permette selezioni molto complesse, basate sulle
 interfacce su cui passano i pacchetti, sugli indirizzi IP, sulle porte, sulle
@@ -2514,6 +2515,7 @@ Si noti come a partire dal secondo pacchetto sia sempre attivo il campo
 quest'ultimo, a partire dal terzo pacchetto, viene espresso in forma relativa
 per maggiore compattezza.  Il campo \texttt{win} in ogni riga indica la
 \textit{advertised window} di cui parlavamo in sez.~\ref{sec:TCP_TCP_opt}.
+
 Allora si può verificare dall'output del comando come venga appunto realizzata
 la sequenza di pacchetti descritta in sez.~\ref{sec:TCP_conn_cre}: prima viene
 inviato dal client un primo pacchetto con il SYN che inizia la connessione, a
@@ -2527,9 +2529,10 @@ una prima riga sul client; al momento in cui facciamo questo si genera una
 sequenza di altri quattro pacchetti. Il primo, dal client al server,
 contraddistinto da una lettera \texttt{P} che significa che il flag PSH è
 impostato, contiene la nostra riga (che è appunto di 11 caratteri), e ad esso
-il server risponde immediatamente con un pacchetto vuoto di ricevuto. Poi
-tocca al server riscrivere indietro quanto gli è stato inviato, per cui sarà
-lui a mandare indietro un terzo pacchetto con lo stesso contenuto appena
+il server risponde immediatamente con un pacchetto vuoto di ricevuto.
+
+Poi tocca al server riscrivere indietro quanto gli è stato inviato, per cui
+sarà lui a mandare indietro un terzo pacchetto con lo stesso contenuto appena
 ricevuto, e a sua volta riceverà dal client un ACK nel quarto pacchetto.
 Questo causerà la ricezione dell'eco nel client che lo stamperà a video.
 
@@ -2617,7 +2620,7 @@ di errore, per questo dovremo riscrivere la funzione \func{ClientEcho}, in
 modo da controllare gli stati di uscita delle varie chiamate. Si è riportata
 la nuova versione della funzione in fig.~\ref{fig:TCP_ClientEcho_second}.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/ClientEcho_second.c}
@@ -2664,19 +2667,20 @@ sez.~\ref{sec:TCP_sock_multiplexing}.
 \label{sec:TCP_conn_crash}
 
 La terminazione del server è solo uno dei possibili scenari di terminazione
-della connessione, un altro caso è ad esempio quello in cui si ha un crollo
-della rete, cosa che potremo simulare facilmente staccando il cavo di rete.
-Un'altra condizione è quella di un blocco della macchina completo della su cui
-gira il server che deve essere riavviata, cosa che potremo simulare eseguendo
-un reset fisico,\footnote{un normale shutdown non va bene; in tal caso infatti
-  il sistema provvede a terminare tutti i processi, per cui la situazione
-  sarebbe sostanzialmente identica alla precedente.} che, in maniera più
-gentile, riavviando la macchina dopo aver interrotto la connessione di rete.
-
-Cominciamo ad analizzare il primo caso, il crollo della rete. Ripetiamo la
-nostra sessione di lavoro precedente, lanciamo il client, scriviamo una prima
-riga, poi stacchiamo il cavo e scriviamo una seconda riga. Il risultato che
-otterremo è:
+della connessione, un altro caso è ad esempio quello in cui si ha
+un'interruzione sulla rete, cosa che potremo simulare facilmente staccando il
+cavo di rete.  Un'altra condizione è quella di un blocco completo della
+macchina su cui gira il server che deve essere riavviata, cosa che potremo
+simulare sia eseguendo un reset fisico (un normale shutdown non va bene; in
+tal caso infatti il sistema provvede a terminare tutti i processi, per cui la
+situazione sarebbe sostanzialmente identica alla precedente) oppure, in
+maniera più gentile, riavviando la macchina dopo aver interrotto la
+connessione di rete.
+
+Cominciamo ad analizzare il primo caso, l'interruzione del collegamento di
+rete. Ripetiamo la nostra sessione di lavoro precedente, lanciamo il client,
+scriviamo una prima riga, poi stacchiamo il cavo e scriviamo una seconda
+riga. Il risultato che otterremo è:
 \begin{Console}
 [piccardi@gont sources]$ \textbf{./echo 192.168.1.141}
 Prima riga
@@ -2771,7 +2775,7 @@ quando la macchina è su una rete remota, è \errcode{ENETUNREACH}; esso viene
 riportato alla ricezione di un pacchetto ICMP di \textit{destination
   unreachable} da parte del router che individua l'interruzione della
 connessione. Di nuovo anche qui il risultato finale dipende da quale è il
-meccanismo più veloce ad accorgersi del problema.
+meccanismo più veloce che porta ad accorgersi del problema.
 
 Se però agiamo sui parametri del kernel, e scriviamo in \file{tcp\_retries2}
 un valore di tentativi più basso, possiamo evitare la scadenza della
@@ -2860,15 +2864,15 @@ sez.~\ref{sec:sock_generic_options}) che provvede all'esecuzione di questo
 controllo.
 
 
-\section{L'uso dell'I/O multiplexing}
+\section{L'uso dell'\textit{I/O multiplexing}}
 \label{sec:TCP_sock_multiplexing}
 
-Affronteremo in questa sezione l'utilizzo dell'I/O multiplexing, affrontato in
-sez.~\ref{sec:file_multiplexing}, nell'ambito delle applicazioni di rete. Già
-in sez.~\ref{sec:TCP_server_crash} era emerso il problema relativo al client
-del servizio echo che non era in grado di accorgersi della terminazione
-precoce del server, essendo bloccato nella lettura dei dati immessi da
-tastiera.
+Affronteremo in questa sezione l'utilizzo dell'\textit{I/O multiplexing},
+affrontato in sez.~\ref{sec:file_multiplexing}, nell'ambito delle applicazioni
+di rete. Già in sez.~\ref{sec:TCP_server_crash} era emerso il problema
+relativo al client del servizio \textit{echo} che non era in grado di
+accorgersi della terminazione precoce del server, essendo bloccato nella
+lettura dei dati immessi da tastiera.
 
 Abbiamo visto in sez.~\ref{sec:file_multiplexing} quali sono le funzionalità
 del sistema che ci permettono di tenere sotto controllo più file descriptor in
@@ -2882,9 +2886,9 @@ asincrona, per cui riprenderemo l'argomento in questa sezione.
 \subsection{Il comportamento della funzione \func{select} con i socket.}
 \label{sec:TCP_sock_select}
 
-Iniziamo con la prima delle funzioni usate per l'I/O multiplexing,
+Iniziamo con la prima delle funzioni usate per l'\textit{I/O multiplexing},
 \func{select}; il suo funzionamento è già stato descritto in dettaglio in
-sez.~\ref{sec:file_multiplexing} e non staremo a ripetere quanto detto lì; 
+sez.~\ref{sec:file_multiplexing} e non staremo a ripetere quanto detto lì;
 sappiamo che la funzione ritorna quando uno o più dei file descriptor messi
 sotto controllo è pronto per la relativa operazione.
 
@@ -2914,10 +2918,10 @@ pronto per la lettura sono le seguenti:
   sez.~\ref{sec:TCP_conn_term}) sulla connessione. In questo caso una
   operazione di lettura avrà successo, ma non risulteranno presenti dati (in
   sostanza \func{read} ritornerà con un valore nullo) per indicare la
-  condizione di end-of-file.
+  condizione di \textit{end-of-file}.
 \item c'è stato un errore sul socket. In questo caso una operazione di lettura
   non si bloccherà ma restituirà una condizione di errore (ad esempio
-  \func{read} restituirà -1) e imposterà la variabile \var{errno} al relativo
+  \func{read} restituirà $-1$) e imposterà la variabile \var{errno} al relativo
   valore. Vedremo in sez.~\ref{sec:sock_generic_options} come sia possibile
   estrarre e cancellare gli errori pendenti su un socket senza usare
   \func{read} usando l'opzione \const{SO\_ERROR}.
@@ -2939,7 +2943,7 @@ pronto per la scrittura sono le seguenti:
   valore della \textsl{soglia di basso livello} in scrittura ed inoltre o il
   socket è già connesso o non necessita (ad esempio è UDP) di connessione.  Il
   valore della soglia è espresso in numero di byte e può essere impostato con
-  l'opzione del socket \const{SO\_SNDLOWAT} (trattata in
+  l'opzione del socket \const{SO\_SNDLOWAT} (trattata in 
   sez.~\ref{sec:sock_generic_options}); il suo valore di default è 2048 per i
   socket TCP e UDP. In questo caso una operazione di scrittura non si
   bloccherà e restituirà un valore positivo pari al numero di byte accettati
@@ -2983,11 +2987,11 @@ quando c'è la certezza di avere dati a sufficienza.\footnote{questo tipo di
 
 
 
-\subsection{Un esempio di I/O multiplexing}
+\subsection{Un esempio di \textit{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
+Abbiamo incontrato la problematica tipica che conduce all'uso dell'\textit{I/O
+  multiplexing} nella nostra analisi degli errori in
 sez.~\ref{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 \textit{standard input}.
@@ -2996,7 +3000,7 @@ In questo caso il problema è quello di dover tenere sotto controllo due
 diversi file descriptor, lo \textit{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
+risposta. L'uso dell'\textit{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
@@ -3010,7 +3014,7 @@ 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}[!htbp]
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{\codesamplewidth}
     \includecodesample{listati/ClientEcho_third.c}
@@ -3044,15 +3048,15 @@ viene ripetuto indefinitamente. Per ogni ciclo si reinizializza
 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 relativi,
-che quindi devono essere reimpostati all'inizio di ogni ciclo.
+  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 sono passati tutti puntatori nulli, non
-interessando né il controllo delle altre attività, né l'impostazione di un
-valore di timeout.
+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})
@@ -3068,24 +3072,25 @@ 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 (\texttt{\small 27--30}) si è avuto un errore e pertanto si
-esce immediatamente segnalandolo, se è nullo (\texttt{\small 31--34})
-significa che il server ha chiuso la connessione, e di nuovo si esce con
-stampando prima un messaggio di avviso, altrimenti (\texttt{\small 35--39}) si
+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.
+  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.
+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
@@ -3113,13 +3118,14 @@ 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:
+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
@@ -3140,56 +3146,61 @@ 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}.
+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. È
+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.\footnote{abbiamo incontrato questa situazione nei vari scenari critici
-  di sez.~\ref{sec:TCP_echo_critical}.}
+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ì
+È 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 è
-``\textit{half closed}''.
+\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 rileggere quanto l'altro capo può continuare a
-scrivere. Per poter permettere allora di segnalare che si è concluso 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ò allora usare la funzione \funcd{shutdown}, il cui
-prototipo è:
-\begin{prototype}{sys/socket.h}
-{int shutdown(int sockfd, int how)}
+capo del socket, si può usare la funzione \funcd{shutdown}, il cui prototipo
+è:
 
-Chiude un lato della connessione fra due socket.
-  
-  \bodydesc{La funzione restituisce zero in caso di successo e -1 per un
-    errore, nel qual caso \var{errno} assumerà i valori:
+\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{ENOTSOCK}] il file descriptor non corrisponde a un socket.
+  \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.
-  \end{errlist}
-  ed inoltre \errval{EBADF}.}
-\end{prototype}
+  \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
@@ -3218,10 +3229,12 @@ 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 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 è
+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
@@ -3233,7 +3246,9 @@ 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
+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,
@@ -3251,9 +3266,10 @@ 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
+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}
@@ -3267,7 +3283,7 @@ 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
+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
@@ -3277,15 +3293,15 @@ denominazione inglese \itindex{Round~Trip~Time~(RTT)} \textit{Round Trip
 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 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.
+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
@@ -3323,7 +3339,7 @@ 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
-subordinato ad un valore nullo di \var{eof} l'impostazione del file descriptor
+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
@@ -3344,30 +3360,31 @@ 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
+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 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à
+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'I/O multiplexing}
+\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'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}.}
+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
@@ -3378,7 +3395,7 @@ 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'I/O multiplexing.}
+  \caption{Schema del nuovo server echo basato sull'\textit{I/O multiplexing}.}
   \label{fig:TCP_echo_multiplex}
 \end{figure}
 
@@ -3405,7 +3422,7 @@ disponibile coi sorgenti allegati nel file \texttt{select\_echod.c}.
 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
+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.
@@ -3414,19 +3431,19 @@ Prima di entrare nel ciclo principale (\texttt{\small 6--56}) 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,\footnote{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.
+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 7--10}) 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 7}) ogni volta il suo azzeramento, per poi
-procedere con il ciclo (\texttt{\small 8--10}) in cui si impostano i socket
-trovati attivi.
+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 7}) ogni volta il suo azzeramento per poi procedere
+con il ciclo (\texttt{\small 8--10}) 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
@@ -3436,10 +3453,10 @@ 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 9}) 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, dato che nelle
-  operazioni i socket saranno aperti e chiusi in corrispondenza della
-  creazione e conclusione delle connessioni, si potranno sempre avere dei
-  \textsl{buchi} nella nostra tabella.} e impostare \var{fset} di conseguenza.
+  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
@@ -3454,14 +3471,14 @@ uscire stampando un messaggio di errore.
 Se invece la funzione ritorna normalmente avremo in \var{n} il numero di
 socket da controllare. Nello specifico si danno due possibili casi diversi per
 cui \func{select} può essere ritornata: o si è ricevuta una nuova connessione
-ed è pronto il socket in ascolto, sul quale si può eseguire \func{accept} o
+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 17--26}): si
 controlla (\texttt{\small 17}) che il socket in ascolto sia fra quelli attivi,
 nel qual caso anzitutto (\texttt{\small 18}) se ne decrementa il numero in
-\var{n}; poi, inizializzata (\texttt{\small 19}) la lunghezza della struttura
+\var{n}. Poi, inizializzata (\texttt{\small 19}) la lunghezza della struttura
 degli indirizzi, si esegue \func{accept} per ottenere il nuovo socket connesso
 controllando che non ci siano errori (\texttt{\small 20--23}). In questo caso
 non c'è più la necessità di controllare per interruzioni dovute a segnali, in
@@ -3471,18 +3488,20 @@ file descriptor alla tabella di quelli connessi, ed inoltre, se è il caso,
 aggiornare (\texttt{\small 25}) il valore massimo in \var{max\_fd}.
 
 Una volta controllato l'arrivo di nuove connessioni si passa a verificare se
-vi sono dati sui socket connessi, per questo si ripete un ciclo
+ci sono dati sui socket connessi, per questo si ripete un ciclo
 (\texttt{\small 29--55}) fintanto che il numero di socket attivi \var{n} resta
 diverso da zero; in questo modo se l'unico socket con attività era quello
 connesso, avendo opportunamente decrementato il contatore, il ciclo verrà
-saltato, e si ritornerà immediatamente (ripetuta l'inizializzazione del
-\textit{file descriptor set} con i nuovi valori nella tabella) alla chiamata
-di \func{accept}. 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à
+saltato e si ritornerà immediatamente, ripetuta l'inizializzazione del
+\textit{file descriptor set} con i nuovi valori nella tabella, alla chiamata
+di \func{accept}. 
+
+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 comunque si inizializza (\texttt{\small
-  28}) 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.
+  28}) 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 30}) nella verifica è incrementare il valore
 dell'indice \var{i} per posizionarsi sul primo valore possibile per un file
@@ -3494,15 +3513,15 @@ attivi, e nel caso si esegue (\texttt{\small 33}) una lettura, uscendo con un
 messaggio in caso di errore (\texttt{\small 34--38}).
 
 Se (\texttt{\small 39}) il numero di byte letti \var{nread} è nullo si è in
-presenza del caso di un \textit{end-of-file}, indice che una connessione che
-si è chiusa, che deve essere trattato (\texttt{\small 39--48}) opportunamente.
-Il primo passo è chiudere (\texttt{\small 40}) anche il proprio capo del
-socket e rimuovere (\texttt{\small 41}) il file descriptor dalla tabella di
-quelli aperti, inoltre occorre verificare (\texttt{\small 42}) se il file
-descriptor chiuso è quello con il valore più alto, nel qual caso occorre
-trovare (\texttt{\small 42--46}) il nuovo massimo, altrimenti (\texttt{\small
-  47}) si può ripetere il ciclo da capo per esaminare (se ne restano)
-ulteriori file descriptor attivi.
+presenza di un \textit{end-of-file}, indice che una connessione che si è
+chiusa, che deve essere trattato (\texttt{\small 39--48}) opportunamente.  Il
+primo passo è chiudere (\texttt{\small 40}) anche il proprio capo del socket e
+rimuovere (\texttt{\small 41}) il file descriptor dalla tabella di quelli
+aperti, inoltre occorre verificare (\texttt{\small 42}) se il file descriptor
+chiuso è quello con il valore più alto, nel qual caso occorre trovare
+(\texttt{\small 42--46}) il nuovo massimo, altrimenti (\texttt{\small 47}) 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
@@ -3521,11 +3540,12 @@ 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à.
+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
@@ -3533,8 +3553,9 @@ 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
+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
@@ -3547,22 +3568,21 @@ modalità non bloccante, concludendo le operazioni qualora non vadano a buon
 fine.
 
 
-
-\subsection{I/O multiplexing con \func{poll}}
+\subsection{\textit{I/O multiplexing} con \func{poll}}
 \label{sec:TCP_serv_poll}
 
-Finora abbiamo trattato le problematiche risolubili con l'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
+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.\footnote{non soffrendo
-  delle limitazioni dovute all'uso dei \textit{file descriptor set}.}
+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
+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:
@@ -3679,7 +3699,7 @@ altrimenti si provvederà (\texttt{\small 32}) a decrementare il numero \var{n}
 di file descriptor attivi da controllare e ad eseguire (\texttt{\small 33}) la
 lettura, ed in caso di errore (\texttt{\small 34--37}) al solito lo si
 notificherà uscendo immediatamente. Qualora invece si ottenga una condizione
-di end-of-file (\texttt{\small 38--47}) si provvederà a chiudere
+di \textit{end-of-file} (\texttt{\small 38--47}) si provvederà a chiudere
 (\texttt{\small 39}) anche il nostro capo del socket e a marcarlo
 (\texttt{\small 40}) nella struttura ad esso associata come inutilizzato.
 Infine dovrà essere ricalcolato (\texttt{\small 41--45}) un eventuale nuovo
@@ -3689,7 +3709,7 @@ sul socket.
 
 Se invece si sono letti dei dati si provvede (\texttt{\small 48}) ad
 effettuarne la riscrittura all'indietro, con il solito controllo ed eventuale
-uscita e notifica in caso si errore (\texttt{\small 49--52}).
+uscita e notifica in caso di errore (\texttt{\small 49--52}).
 
 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};
@@ -3699,8 +3719,7 @@ dai dati in ingresso. Si applicano comunque anche a questo server le
 considerazioni finali di sez.~\ref{sec:TCP_serv_select}.
 
 
-
-\subsection{I/O multiplexing con \textit{epoll}}
+\subsection{\textit{I/O multiplexing} con \textit{epoll}}
 \label{sec:TCP_serv_epoll}
 
 Da fare.