Materuale vario, correzioni e aggiornamenti sulla code di messaggi
[gapil.git] / tcpsock.tex
index 3786c86bdc7c68b6cbc58a2ddf906093c7a3f212..8118b1e49db1067d5ae69627623a2daac271e736 100644 (file)
@@ -1,6 +1,6 @@
 %% tcpsock.tex
 %%
 %% tcpsock.tex
 %%
-%% Copyright (C) 2000-2012 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2014 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
@@ -135,12 +135,13 @@ comunicare all'altro capo una serie di parametri utili a regolare la
 connessione.  Normalmente vengono usate le seguenti opzioni:
 
 \begin{itemize}
 connessione.  Normalmente vengono usate le seguenti opzioni:
 
 \begin{itemize}
-\item \textit{MSS option}, dove MMS sta per \itindex{Maximum~Segment~Size}
-  \textit{Maximum Segment Size}, con questa opzione ciascun capo della
-  connessione annuncia all'altro il massimo ammontare di dati che vorrebbe
-  accettare per ciascun segmento nella connessione corrente. È possibile
-  leggere e scrivere questo valore attraverso l'opzione del socket
-  \const{TCP\_MAXSEG} (vedi sez.~\ref{sec:sock_tcp_udp_options}).
+\item \textit{MSS option}, dove MMS sta per
+  \itindex{Maximum~Segment~Size~(MSS)} \textit{Maximum Segment Size}, con
+  questa opzione ciascun capo della connessione annuncia all'altro il massimo
+  ammontare di dati che vorrebbe accettare per ciascun segmento nella
+  connessione corrente. È possibile leggere e scrivere questo valore
+  attraverso l'opzione del socket \const{TCP\_MAXSEG} (vedi
+  sez.~\ref{sec:sock_tcp_udp_options}).
   
 \item \textit{window scale option}, il protocollo TCP implementa il controllo
   di flusso attraverso una \itindex{advertised~window} \textit{advertised
   
 \item \textit{window scale option}, il protocollo TCP implementa il controllo
   di flusso attraverso una \itindex{advertised~window} \textit{advertised
@@ -179,8 +180,8 @@ connessione.  Normalmente vengono usate le seguenti opzioni:
 
 \end{itemize}
 
 
 \end{itemize}
 
-La MSS \itindex{Maximum~Segment~Size} è generalmente supportata da quasi tutte
-le implementazioni del protocollo, le ultime due opzioni (trattate
+La MSS \itindex{Maximum~Segment~Size~(MSS)} è generalmente supportata da quasi
+tutte le implementazioni del protocollo, le ultime due opzioni (trattate
 nell'\href{http://www.ietf.org/rfc/rfc1323.txt}{RFC~1323}) sono meno comuni;
 vengono anche dette \textit{long fat pipe options} dato che questo è il nome
 che viene dato alle connessioni caratterizzate da alta velocità o da ritardi
 nell'\href{http://www.ietf.org/rfc/rfc1323.txt}{RFC~1323}) sono meno comuni;
 vengono anche dette \textit{long fat pipe options} dato che questo è il nome
 che viene dato alle connessioni caratterizzate da alta velocità o da ritardi
@@ -304,9 +305,9 @@ che il protocollo viene ad assumere per i due lati, server e client.
 \end{figure}
 
 La connessione viene iniziata dal client che annuncia una
 \end{figure}
 
 La connessione viene iniziata dal client che annuncia una
-\itindex{Maximum~Segment~Size} MSS di 1460, un valore tipico con Linux per
-IPv4 su Ethernet, il server risponde con lo stesso valore (ma potrebbe essere
-anche un valore diverso).
+\itindex{Maximum~Segment~Size~(MSS)} MSS di 1460, un valore tipico con Linux
+per IPv4 su Ethernet, il server risponde con lo stesso valore (ma potrebbe
+essere anche un valore diverso).
 
 Una volta che la connessione è stabilita il client scrive al server una
 richiesta (che assumiamo stare in un singolo segmento, cioè essere minore dei
 
 Una volta che la connessione è stabilita il client scrive al server una
 richiesta (che assumiamo stare in un singolo segmento, cioè essere minore dei
@@ -1100,8 +1101,9 @@ eventualmente ripetere la chiamata alla funzione come per l'errore di
 Un'altra differenza con BSD è che la funzione non fa ereditare al nuovo socket
 i flag del socket originale, come \const{O\_NONBLOCK},\footnote{ed in generale
   tutti quelli che si possono impostare con \func{fcntl}, vedi
 Un'altra differenza con BSD è che la funzione non fa ereditare al nuovo socket
 i flag del socket originale, come \const{O\_NONBLOCK},\footnote{ed in generale
   tutti quelli che si possono impostare con \func{fcntl}, vedi
-  sez.~\ref{sec:file_fcntl}.} che devono essere rispecificati ogni volta. Tutto
-questo deve essere tenuto in conto se si devono scrivere programmi portabili.
+  sez.~\ref{sec:file_fcntl_ioctl}.} che devono essere rispecificati ogni
+volta. Tutto questo deve essere tenuto in conto se si devono scrivere
+programmi portabili.
 
 Il meccanismo di funzionamento di \func{accept} è essenziale per capire il
 funzionamento di un server: in generale infatti c'è sempre un solo socket in
 
 Il meccanismo di funzionamento di \func{accept} è essenziale per capire il
 funzionamento di un server: in generale infatti c'è sempre un solo socket in
@@ -1221,9 +1223,9 @@ socket BSD fanno questa assunzione.
 \subsection{La funzione \func{close}}
 \label{sec:TCP_func_close}
 
 \subsection{La funzione \func{close}}
 \label{sec:TCP_func_close}
 
-La funzione standard Unix \func{close} (vedi sez.~\ref{sec:file_close}) che si
-usa sui file può essere usata con lo stesso effetto anche sui file descriptor
-associati ad un socket.
+La funzione standard Unix \func{close} (vedi sez.~\ref{sec:file_open_close})
+che si usa sui file può essere usata con lo stesso effetto anche sui file
+descriptor associati ad un socket.
 
 L'azione di questa funzione quando applicata a socket è di marcarlo come
 chiuso e ritornare immediatamente al processo. Una volta chiamata il socket
 
 L'azione di questa funzione quando applicata a socket è di marcarlo come
 chiuso e ritornare immediatamente al processo. Una volta chiamata il socket
@@ -1240,9 +1242,9 @@ Come per tutti i file descriptor anche per i socket viene mantenuto un numero
 di riferimenti, per cui se più di un processo ha lo stesso socket aperto
 l'emissione del FIN e la sequenza di chiusura di TCP non viene innescata
 fintanto che il numero di riferimenti non si annulla, questo si applica, come
 di riferimenti, per cui se più di un processo ha lo stesso socket aperto
 l'emissione del FIN e la sequenza di chiusura di TCP non viene innescata
 fintanto che il numero di riferimenti non si annulla, questo si applica, come
-visto in sez.~\ref{sec:file_sharing}, sia ai file descriptor duplicati che a
-quelli ereditati dagli eventuali processi figli, ed è il comportamento che ci
-si aspetta in una qualunque applicazione client/server.
+visto in sez.~\ref{sec:file_shared_access}, sia ai file descriptor duplicati
+che a quelli ereditati dagli eventuali processi figli, ed è il comportamento
+che ci si aspetta in una qualunque applicazione client/server.
 
 Per attivare immediatamente l'emissione del FIN e la sequenza di chiusura
 descritta in sez.~\ref{sec:TCP_conn_term}, si può invece usare la funzione
 
 Per attivare immediatamente l'emissione del FIN e la sequenza di chiusura
 descritta in sez.~\ref{sec:TCP_conn_term}, si può invece usare la funzione
@@ -1323,9 +1325,10 @@ disponibile fra i sorgenti allegati alla guida nei file \file{FullRead.c} e
 
 Come si può notare le due funzioni ripetono la lettura/scrittura in un ciclo
 fino all'esaurimento del numero di byte richiesti, in caso di errore viene
 
 Come si può notare le due funzioni ripetono la lettura/scrittura in un ciclo
 fino all'esaurimento del numero di byte richiesti, in caso di errore viene
-controllato se questo è \errcode{EINTR} (cioè un'interruzione della system
-call dovuta ad un segnale), nel qual caso l'accesso viene ripetuto, altrimenti
-l'errore viene ritornato al programma chiamante, interrompendo il ciclo.
+controllato se questo è \errcode{EINTR} (cioè un'interruzione della
+\textit{system call} dovuta ad un segnale), nel qual caso l'accesso viene
+ripetuto, altrimenti l'errore viene ritornato al programma chiamante,
+interrompendo il ciclo.
 
 Nel caso della lettura, se il numero di byte letti è zero, significa che si è
 arrivati alla fine del file (per i socket questo significa in genere che
 
 Nel caso della lettura, se il numero di byte letti è zero, significa che si è
 arrivati alla fine del file (per i socket questo significa in genere che
@@ -1383,7 +1386,7 @@ il numero della porta del servizio. Il primo passo (\texttt{\small 20}) è
 inizializzare tutto a zero, per poi inserire il tipo di indirizzo
 (\texttt{\small 21}) e la porta (\texttt{\small 22}), usando per quest'ultima
 la funzione \func{htons} per convertire il formato dell'intero usato dal
 inizializzare tutto a zero, per poi inserire il tipo di indirizzo
 (\texttt{\small 21}) e la porta (\texttt{\small 22}), usando per quest'ultima
 la funzione \func{htons} per convertire il formato dell'intero usato dal
-computer a quello usato nella rete, infine \texttt{\small 23--27} si può
+computer a quello usato nella rete, infine (\texttt{\small 23--27}) si può
 utilizzare la funzione \func{inet\_pton} per convertire l'indirizzo numerico
 passato dalla linea di comando.
 
 utilizzare la funzione \func{inet\_pton} per convertire l'indirizzo numerico
 passato dalla linea di comando.
 
@@ -2060,11 +2063,11 @@ all'esempio illustrato in fig.~\ref{fig:TCP_echo_server_first_code}.
 
 In questo modo però si introduce un altro problema. Si ricordi infatti che,
 come spiegato in sez.~\ref{sec:sig_gen_beha}, quando un programma si trova in
 
 In questo modo però si introduce un altro problema. Si ricordi infatti che,
 come spiegato in sez.~\ref{sec:sig_gen_beha}, quando un programma si trova in
-stato di \texttt{sleep} durante l'esecuzione di una system call, questa viene
-interrotta alla ricezione di un segnale. Per questo motivo, alla fine
-dell'esecuzione del gestore del segnale, se questo ritorna, il programma
-riprenderà l'esecuzione ritornando dalla system call interrotta con un errore
-di \errcode{EINTR}.
+stato di \texttt{sleep} durante l'esecuzione di una \textit{system call},
+questa viene interrotta alla ricezione di un segnale. Per questo motivo, alla
+fine dell'esecuzione del gestore del segnale, se questo ritorna, il programma
+riprenderà l'esecuzione ritornando dalla \textit{system call} interrotta con
+un errore di \errcode{EINTR}.
 
 Vediamo allora cosa comporta tutto questo nel nostro caso: quando si chiude il
 client, il processo figlio che gestisce la connessione terminerà, ed il padre,
 
 Vediamo allora cosa comporta tutto questo nel nostro caso: quando si chiude il
 client, il processo figlio che gestisce la connessione terminerà, ed il padre,
@@ -2081,13 +2084,13 @@ accept error: Interrupted system call
 \end{verbatim}%#
 
 Come accennato in sez.~\ref{sec:sig_gen_beha} le conseguenze di questo
 \end{verbatim}%#
 
 Come accennato in sez.~\ref{sec:sig_gen_beha} le conseguenze di questo
-comportamento delle system call possono essere superate in due modi diversi,
-il più semplice è quello di modificare il codice di \func{Signal} per
-richiedere il riavvio automatico delle system call interrotte secondo la
-semantica di BSD, usando l'opzione \const{SA\_RESTART} di \func{sigaction};
-rispetto a quanto visto in fig.~\ref{fig:sig_Signal_code}. Definiremo allora la
-nuova funzione \func{SignalRestart}\footnote{anche questa è definita, insieme
-  alle altre funzioni riguardanti la gestione dei segnali, nel file
+comportamento delle \textit{system call} possono essere superate in due modi
+diversi, il più semplice è quello di modificare il codice di \func{Signal} per
+richiedere il riavvio automatico delle \textit{system call} interrotte secondo
+la semantica di BSD, usando l'opzione \const{SA\_RESTART} di \func{sigaction};
+rispetto a quanto visto in fig.~\ref{fig:sig_Signal_code}. Definiremo allora
+la nuova funzione \func{SignalRestart}\footnote{anche questa è definita,
+  insieme alle altre funzioni riguardanti la gestione dei segnali, nel file
   \file{SigHand.c}, il cui contento completo può essere trovato negli esempi
   allegati.} come mostrato in fig.~\ref{fig:sig_SignalRestart_code}, ed
 installeremo il gestore usando quest'ultima.
   \file{SigHand.c}, il cui contento completo può essere trovato negli esempi
   allegati.} come mostrato in fig.~\ref{fig:sig_SignalRestart_code}, ed
 installeremo il gestore usando quest'ultima.
@@ -2099,30 +2102,30 @@ installeremo il gestore usando quest'ultima.
   \end{minipage}  
   \normalsize 
   \caption{La funzione \func{SignalRestart}, che installa un gestore di
   \end{minipage}  
   \normalsize 
   \caption{La funzione \func{SignalRestart}, che installa un gestore di
-    segnali in semantica BSD per il riavvio automatico delle system call
-    interrotte.}
+    segnali in semantica BSD per il riavvio automatico delle \textit{system
+      call} interrotte.}
   \label{fig:sig_SignalRestart_code}
 \end{figure}
 
 Come si può notare questa funzione è identica alla precedente \func{Signal},
   \label{fig:sig_SignalRestart_code}
 \end{figure}
 
 Come si può notare questa funzione è identica alla precedente \func{Signal},
-illustrata in fig.~\ref{fig:sig_Signal_code}, solo che in questo caso invece di
-inizializzare a zero il campo \var{sa\_flags} di \struct{sigaction}, lo si
+illustrata in fig.~\ref{fig:sig_Signal_code}, solo che in questo caso invece
+di inizializzare a zero il campo \var{sa\_flags} di \struct{sigaction}, lo si
 inizializza (\texttt{\small 5}) al valore \const{SA\_RESTART}. Usando questa
 funzione al posto di \func{Signal} nel server non è necessaria nessuna altra
 inizializza (\texttt{\small 5}) al valore \const{SA\_RESTART}. Usando questa
 funzione al posto di \func{Signal} nel server non è necessaria nessuna altra
-modifica: le system call interrotte saranno automaticamente riavviate, e
-l'errore \errcode{EINTR} non si manifesterà più.
+modifica: le \textit{system call} interrotte saranno automaticamente
+riavviate, e l'errore \errcode{EINTR} non si manifesterà più.
 
 La seconda soluzione è più invasiva e richiede di controllare tutte le volte
 
 La seconda soluzione è più invasiva e richiede di controllare tutte le volte
-l'errore restituito dalle varie system call, ripetendo la chiamata qualora
-questo corrisponda ad \errcode{EINTR}. Questa soluzione ha però il pregio
-della portabilità, infatti lo standard POSIX dice che la funzionalità di
-riavvio automatico delle system call, fornita da \const{SA\_RESTART}, è
-opzionale, per cui non è detto che essa sia disponibile su qualunque sistema.
-Inoltre in certi casi,\footnote{Stevens in \cite{UNP1} accenna che la maggior
-  parte degli Unix derivati da BSD non fanno ripartire \func{select}; altri
-  non riavviano neanche \func{accept} e \func{recvfrom}, cosa che invece nel
-  caso di Linux viene sempre fatta.} anche quando questa è presente, non è
-detto possa essere usata con \func{accept}. 
+l'errore restituito dalle varie \textit{system call}, ripetendo la chiamata
+qualora questo corrisponda ad \errcode{EINTR}. Questa soluzione ha però il
+pregio della portabilità, infatti lo standard POSIX dice che la funzionalità
+di riavvio automatico delle \textit{system call}, fornita da
+\const{SA\_RESTART}, è opzionale, per cui non è detto che essa sia disponibile
+su qualunque sistema.  Inoltre in certi casi,\footnote{Stevens in \cite{UNP1}
+  accenna che la maggior parte degli Unix derivati da BSD non fanno ripartire
+  \func{select}; altri non riavviano neanche \func{accept} e \func{recvfrom},
+  cosa che invece nel caso di Linux viene sempre fatta.} anche quando questa è
+presente, non è detto possa essere usata con \func{accept}.
 
 
 La portabilità nella gestione dei segnali però viene al costo di una
 
 
 La portabilità nella gestione dei segnali però viene al costo di una
@@ -2158,7 +2161,7 @@ programma.
   \normalsize
   \caption{La sezione nel codice della seconda versione del server
     per il servizio \textit{echo} modificata per tener conto dell'interruzione
   \normalsize
   \caption{La sezione nel codice della seconda versione del server
     per il servizio \textit{echo} modificata per tener conto dell'interruzione
-    delle system call.}
+    delle \textit{system call}.}
   \label{fig:TCP_echo_server_code_second}
 \end{figure}
 
   \label{fig:TCP_echo_server_code_second}
 \end{figure}
 
@@ -2180,12 +2183,12 @@ eventuale pausa con una condizione (\texttt{\small 21}) sulla variabile
 numero di secondi da aspettare (il valore preimpostato è nullo).
 
 Si è potuto lasciare inalterata tutta la sezione di creazione del socket
 numero di secondi da aspettare (il valore preimpostato è nullo).
 
 Si è potuto lasciare inalterata tutta la sezione di creazione del socket
-perché nel server l'unica chiamata ad una system call lenta, che può essere
-interrotta dall'arrivo di \signal{SIGCHLD}, è quella ad \func{accept}, che è
-l'unica funzione che può mettere il processo padre in stato di sleep nel
+perché nel server l'unica chiamata ad una \textit{system call} lenta, che può
+essere interrotta dall'arrivo di \signal{SIGCHLD}, è quella ad \func{accept},
+che è l'unica funzione che può mettere il processo padre in stato di sleep nel
 periodo in cui un figlio può terminare; si noti infatti come le altre
 periodo in cui un figlio può terminare; si noti infatti come le altre
-\index{system~call~lente} \textit{slow system call}\footnote{si ricordi la
-  distinzione fatta in sez.~\ref{sec:sig_gen_beha}.} o sono chiamate prima di
+\index{system~call~lente} \textit{system call} lente (si ricordi la
+distinzione fatta in sez.~\ref{sec:sig_gen_beha}) o sono chiamate prima di
 entrare nel ciclo principale, quando ancora non esistono processi figli, o
 sono chiamate dai figli stessi e non risentono di \signal{SIGCHLD}.
 
 entrare nel ciclo principale, quando ancora non esistono processi figli, o
 sono chiamate dai figli stessi e non risentono di \signal{SIGCHLD}.
 
@@ -2465,15 +2468,16 @@ avanti in sez.~\ref{sec:TCP_shutdown} la chiusura di un solo capo di un socket
 è una operazione lecita, per cui la nostra scrittura avrà comunque successo
 (come si può constatare lanciando usando \cmd{strace}\footnote{il comando
   \cmd{strace} è un comando di debug molto utile che prende come argomento un
 è una operazione lecita, per cui la nostra scrittura avrà comunque successo
 (come si può constatare lanciando usando \cmd{strace}\footnote{il comando
   \cmd{strace} è un comando di debug molto utile che prende come argomento un
-  altro comando e ne stampa a video tutte le invocazioni di una system call,
-  coi relativi argomenti e valori di ritorno, per cui usandolo in questo
-  contesto potremo verificare che effettivamente la \func{write} ha scritto la
-  riga, che in effetti è stata pure trasmessa via rete.}), in quanto il nostro
-programma non ha a questo punto alcun modo di sapere che dall'altra parte non
-c'è più nessuno processo in grado di leggere quanto scriverà. Questo sarà
-chiaro solo dopo il tentativo di scrittura, e la ricezione del segmento RST di
-risposta che indica che dall'altra parte non si è semplicemente chiuso un capo
-del socket, ma è completamente terminato il programma.
+  altro comando e ne stampa a video tutte le invocazioni di una \textit{system
+    call}, coi relativi argomenti e valori di ritorno, per cui usandolo in
+  questo contesto potremo verificare che effettivamente la \func{write} ha
+  scritto la riga, che in effetti è stata pure trasmessa via rete.}), in
+quanto il nostro programma non ha a questo punto alcun modo di sapere che
+dall'altra parte non c'è più nessuno processo in grado di leggere quanto
+scriverà. Questo sarà chiaro solo dopo il tentativo di scrittura, e la
+ricezione del segmento RST di risposta che indica che dall'altra parte non si
+è semplicemente chiuso un capo del socket, ma è completamente terminato il
+programma.
 
 Per questo motivo il nostro client proseguirà leggendo dal socket, e dato che
 questo è stato chiuso avremo che, come spiegato in
 
 Per questo motivo il nostro client proseguirà leggendo dal socket, e dato che
 questo è stato chiuso avremo che, come spiegato in
@@ -3143,7 +3147,7 @@ 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
 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}
+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}.
 
 \textit{Round Trip Time}) ed è quello che viene stimato con l'uso del comando
 \cmd{ping}.
 
@@ -3302,17 +3306,17 @@ 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
 attivi.
 
 Per far questo si usa la caratteristica dei file descriptor, descritta in
-sez.~\ref{sec:file_open}, 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 8}) 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 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.
+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 8}) 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 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.
 
 Una volta inizializzato con i socket aperti il nostro \textit{file descriptor
   set} potremo chiamare \func{select} per fargli osservare lo stato degli
 
 Una volta inizializzato con i socket aperti il nostro \textit{file descriptor
   set} potremo chiamare \func{select} per fargli osservare lo stato degli
@@ -3576,7 +3580,7 @@ sez.~\ref{sec:TCP_serv_select}.
 
 
 
 
 
 
-\subsection{I/O multiplexing con \func{epoll}}
+\subsection{I/O multiplexing con \textit{epoll}}
 \label{sec:TCP_serv_epoll}
 
 Da fare.
 \label{sec:TCP_serv_epoll}
 
 Da fare.