Revisione della sezione su shutdown, iniziato lavoro sulla versione
authorSimone Piccardi <piccardi@gnulinux.it>
Sat, 8 Nov 2003 17:27:11 +0000 (17:27 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sat, 8 Nov 2003 17:27:11 +0000 (17:27 +0000)
multiplexed del server echo, fatta figura esplicativa.

biblio.bib
html/gapil.html
img/TCPechoMult.dia [new file with mode: 0644]
tcpsockadv.tex

index 3b6cf3ba7c06af0620f9aee22b38a0cd1c198a17..79f88b4e009007ad2632e8c818fd82b42dee54e5 100644 (file)
@@ -17,7 +17,7 @@
 @Book{TCPIll1,
   author =      {W. Richard Stevens},
   editor =      {},
-  title =       {TCP/IP Illustrated, the protocols},
+  title =       {TCP/IP Illustrated, Volume 1, the protocols},
   publisher =   {Addison Wesley},
   year =        {1994},
   OPTkey =      {},
index 133db1edc883debac958cbb06b5a31b1be47c439..8ce6a23739595b07a8ae7f2523d3b67a5093cd54 100644 (file)
              </tbody>
            </table>
            <p>
-             <b> Versione corrente:</b> 485 pagine.
+             <b> Versione corrente:</b> 491 pagine.
            </p>
          </td>
        </tr>
          </td>
          <td bgcolor="lightblue"> 
 
+             <b>8 - novembre - 2003</b> <br/> Corretta tabella sbagliata al
+             capitolo 5, completata la sezione sull'uso dell'I/O multiplexing
+             sul lato client ed iniziata la versione server, inserita la
+             trattazione della funzione shutdown.
+           <p>
              <b>21 - settembre - 2003</b> <br/> Completato il capitolo sui
              socket elementari, e corretti numerosi errori. Revisione della
              sezione sull'I/O multiplexing nel capitolo sui file avanzati in
              vista dell'uso nel capitolo sui socket TCP avanzati.
+           </p>
            <p>
              <b>6 - aprile - 2003</b> <br/> Grazie all'incredibile lavoro di
              Mirko Maischberger abbiamo una favolosa versione in HTML, che
diff --git a/img/TCPechoMult.dia b/img/TCPechoMult.dia
new file mode 100644 (file)
index 0000000..ed7a737
Binary files /dev/null and b/img/TCPechoMult.dia differ
index 42367de254762c42737910f7f213a87ff4f84384..d2e58fe5c0e123eaf7d4379458442e8679fef3f1 100644 (file)
@@ -365,7 +365,7 @@ Ci si pu
 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 è
@@ -377,30 +377,32 @@ 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
-\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}%$
@@ -413,30 +415,32 @@ 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, 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
@@ -472,19 +476,20 @@ 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}
-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
@@ -495,15 +500,34 @@ diversa a seconda del valore di \var{eof}. Se infatti questa 
 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}}
@@ -513,7 +537,8 @@ Abbiamo visto in \secref{sec:TCP_serv_select} come creare un server che
 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}