quando questa sembra rendere \funcd{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
+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 è
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
-\func{close} si limiterà a deallocare nel processo corrente il file descriptor
-utilizzato, ma il socket resterà pienamente accessibile attraverso gli altri
-riferimenti.Se torniamo all'esempio di \figref{fig:TCP_echo_server_first_code}
-abbiamo infatti che le due \func{close} (sul socket connesso nel padre e sul
-socket in ascolto nel figlio), restando comunque altri riferimenti attivi (al
-socket connesso nel figlio e a quello in ascolto nel padre) non effettuano
-nessuna chiusura effettiva.
-
-Questo non avviene affatto se si usa \func{shutdown} 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à
-ovviamente efficace anche per tutti gli altri file descriptor con cui si fa
+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
+\figref{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
+\macro{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
-ancora questi potrà inviarci. Questo è ad esempio l'uso che ci serve per
-rendere finalmente completo il nostro esempio sul servizio 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 standard input e
-standard output. Così se eseguiamo:
+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 standard
+input e standard output. Così se eseguiamo:
\begin{verbatim}
[piccardi@gont sources]$ ./echo 192.168.1.1 < ../fileadv.tex > copia
\end{verbatim}%$
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, detto RTT (da \textit{Round Trip Time} può essere
-stimato con l'uso del comando \cmd{ping}. Ma mantre il pacchetti sono in
-transito sulla rete il client continua a leggere e a scrivere fintanto che il
-file in ingresso finisce.
+di processo, questo tempo è quello impiegato nella trasmissione via rete, che
+viene detto RTT (da \textit{Round Trip Time}, e può essere stimato con l'uso
+del comando \cmd{ping}.
A questo punto, se torniamo al codice mostrato in
-\figref{fig:TCP_ClientEcho_third}, notiamo che non appena viene ricevuto un
-end-of-file in ingresso il nostro client termina. Nel caso interattivo, in cui
-si inviavano brevi stringe una alla volta, c'era sempre il tempo di eseguire
-la lettura completa di quanto il server rimandava indietro. In questo caso
-però quando il client termina, essendo la comunicazione a piena velocità, ci
-saranno ancora pacchetti in transito sulla rete, ma siccome il client esce
+\figref{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ò che 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.
-Per evitare questo tipo di problema occorre, invece di uscire, usare
-\func{shutdown} per effettuare la chiusura del socket in scrittura una volta
-completata la lettura del file in ingresso. 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 fino a quando quest'ultimo,
-riconosciuta la chiusura del socket in scrittura da parte del client,
-effettuerà la chiusura dello stesso a sua volta. Solo alla ricezione della
-chiusura del socket da parte del server, si potrà essere sicuri della
-ricezione di tutti i dati prima della terminazione della connessione.
+Per evitare questo tipo di problema, invece di uscire occorre usare
+\func{shutdown} per effettuare la chiusura del lato in scrittura del socket,
+una volta completata la lettura del file in ingresso. 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 anche
+lui, 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 si potrà essere sicuri della ricezione di tutti i
+dati e della terminazione effettiva della connessione.
\begin{figure}[!htb]
\footnotesize \centering
Le maggiori modifiche rispetto alla precedente versione sono invece nella
gestione (\texttt{\small 18--22}) del caso in cui la lettura con \func{fgets}
-restitisca un valore nullo, indice della fine del file, che prima 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 standard input dal file descriptor set.
+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 standard input dal 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 standard input.
+(\texttt{\small 44--48}) sullo 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
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
-connesione.
+connessione.
\subsection{Un server basato sull'I/O multiplexing}
\label{sec:TCP_serv_select}
-Vediamo ora come con l'utilizzo dell'I/O multiplexing diventi possibile
-riscrivere il nostro server \textit{echo} in modo da evitare di dover creare
-un nuovo processo tutte le volte che si ha una connessione.
+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.
+
+La struttura del nuovo server è illustrata in \figref{fig:TCP_echo_multiplex},
+in questo caso avremo un solo processo che ad ogni nuova connessione da parte
+del client sul socket in ascolto inserirà il socket connesso ad essa relativo
+in una opportuna tabella, poi utilizzerà \func{select} per rilevare la
+presenza di dati in arrivo su ciascun socket connesso, riutilizzandolo per
+inviare i dati in risposta.
+
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=13cm]{img/TCPechoMult}
+ \caption{Schema del nuovo server echo basato sull'I/O multiplexing.}
+ \label{fig:TCP_echo_multiplex}
+\end{figure}
+
+
\subsection{Un esempio di I/O multiplexing con \func{poll}}
utilizzi l'I/O multiplexing attraverso l'impiego della funzione \func{select},
ma in \secref{sec:file_multiplexing} abbiamo visto come la funzione
\func{poll} costituisca una alternativa a \func{select} con delle funzionalità
-migliori, vediamo allora come reimplementare il server di
+migliori, vediamo allora come reimplementare il nostro servizio usando questa
+funzione.
\section{Le opzioni dei socket}