Ultimo materiale, rivisto HTML del sito, e iniziato a parlare di select +
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 21 Sep 2003 18:41:27 +0000 (18:41 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 21 Sep 2003 18:41:27 +0000 (18:41 +0000)
socket

fileadv.tex
html/gapil.html
tcpsock.tex
tcpsockadv.tex

index ce328748c716953330fa39a6385250fd58066c41..445d9c73fd613ef378ab181d1ed7924cc6d79a0e 100644 (file)
@@ -192,12 +192,11 @@ rimanente.\footnote{questo pu
 
 Uno dei problemi che si presentano con l'uso di \func{select} è che il suo
 comportamento dipende dal valore del file descriptor che si vuole tenere sotto
 
 Uno dei problemi che si presentano con l'uso di \func{select} è che il suo
 comportamento dipende dal valore del file descriptor che si vuole tenere sotto
-controllo.  Infatti il kernel riceve solo un valore massimo, e dovrà
-effettuare una scansione su tutto l'intervallo, che può essere anche molto
-ampio, per capire quali sono i file descriptor da tenere sotto controllo,
-anche se sono solo poche unità; e questo ha ovviamente un pessimo risultato
-per le prestazioni; il comportamenento viene della funzione viene così a
-dipendere in maniera innaturale dal valore del file decriptor.
+controllo.  Infatti il kernel riceve con \param{n} un valore massimo per tale
+valore, e per capire quali sono i file descriptor da tenere sotto controllo
+dovrà effettuare una scansione su tutto l'intervallo, che può anche essere
+anche molto ampio anche se i file descriptor sono solo poche unità; tutto ciò
+ha ovviamente delle conseguenze ampiamente negative per le prestazioni.
 
 Inoltre c'è anche il problema che il numero massimo dei file che si possono
 tenere sotto controllo, la funzione è nata quando il kernel consentiva un
 
 Inoltre c'è anche il problema che il numero massimo dei file che si possono
 tenere sotto controllo, la funzione è nata quando il kernel consentiva un
@@ -256,27 +255,27 @@ vengono utilizzati solo per \var{revents} come valori in uscita).
 \begin{table}[htb]
   \centering
   \footnotesize
 \begin{table}[htb]
   \centering
   \footnotesize
-  \begin{tabular}[c]{|l|c|l|}
+  \begin{tabular}[c]{|l|l|}
     \hline
     \hline
-    \textbf{Flag} & \textbf{Valore} & \textbf{Significato} \\
+    \textbf{Flag}  & \textbf{Significato} \\
     \hline
     \hline
     \hline
     \hline
-    \const{POLLIN}    & 0x001 & È possibile la lettura immediata.\\
-    \const{POLLPRI}   & 0x002 & Sono presenti dati urgenti.\\
-    \const{POLLOUT}   & 0x004 & È possibile la scrittura immediata.\\
+    \const{POLLIN}    & È possibile la lettura immediata.\\
+    \const{POLLPRI}   & Sono presenti dati urgenti.\\
+    \const{POLLOUT}   & È possibile la scrittura immediata.\\
     \hline
     \hline
-    \const{POLLERR}   & 0x008 & C'è una condizione di errore.\\
-    \const{POLLHUP}   & 0x010 & Si è verificato un hung-up.\\
-    \const{POLLNVAL}  & 0x020 & Il file descriptor non è aperto.\\
+    \const{POLLERR}   & C'è una condizione di errore.\\
+    \const{POLLHUP}   & Si è verificato un hung-up.\\
+    \const{POLLNVAL}  & Il file descriptor non è aperto.\\
     \hline
     \hline
-    \const{POLLRDNORM}& 0x040 & Sono disponibili in lettura dati normali.\\ 
-    \const{POLLRDBAND}& 0x080 & Sono disponibili in lettura dati ad alta 
-                                priorità. \\
-    \const{POLLWRNORM}& 0x100 & È possibile la scrittura di dati normali.  \\ 
-    \const{POLLWRBAND}& 0x200 & È possibile la scrittura di dati ad 
-                                alta priorità. \\
-    \const{POLLMSG}   & 0x400 & Un segnale \const{SIGPOLL} è arrivato alla
-                                cima dello stream.\\
+    \const{POLLRDNORM}& Sono disponibili in lettura dati normali.\\ 
+    \const{POLLRDBAND}& Sono disponibili in lettura dati ad alta 
+                        priorità. \\
+    \const{POLLWRNORM}& È possibile la scrittura di dati normali.  \\ 
+    \const{POLLWRBAND}& È possibile la scrittura di dati ad 
+                        alta priorità. \\
+    \const{POLLMSG}   & Un segnale \const{SIGPOLL} è arrivato alla
+                        cima dello stream (non usato).\\
     \hline    
   \end{tabular}
   \caption{Costanti per l'identificazione dei vari bit dei campi
     \hline    
   \end{tabular}
   \caption{Costanti per l'identificazione dei vari bit dei campi
index d66a73be327e93cf78bf0f5feef755d57a8b3828..7024ee80d5b780f94bc9ec9adb2f8e06c5484f30 100644 (file)
                <tr>
                  <td valign="top"> <b> Cap. 10 </b> </td>
                  <td valign="top"> Sessioni e terminali</td> 
                <tr>
                  <td valign="top"> <b> Cap. 10 </b> </td>
                  <td valign="top"> Sessioni e terminali</td> 
-                 <td valign="top"> Sessioni complete, da revisionare, 
+                 <td valign="top"> sessioni complete, da revisionare, 
                    terminali quasi completi. </td>
                </tr>
                <tr>
                    terminali quasi completi. </td>
                </tr>
                <tr>
                <tr>
                  <td valign="top"> <b> Cap. 12 </b> </td>
                  <td valign="top"> IPC </td> 
                <tr>
                  <td valign="top"> <b> Cap. 12 </b> </td>
                  <td valign="top"> IPC </td> 
-                 <td valign="top"> Pipe, fifo e code, semafori, 
+                 <td valign="top"> pipe, fifo e code, semafori, 
                    memoria condivisa, tecniche alternative completi, da
                    revisionare, IPC POSIX quasi completo. 
                  </td>
                </tr>
                <tr>
                    memoria condivisa, tecniche alternative completi, da
                    revisionare, IPC POSIX quasi completo. 
                  </td>
                </tr>
                <tr>
-                 <td valign="top"> <b> Cap. 13-14 </b> </td>
+                 <td valign="top"> <b> Cap. 13 </b> </td>
                  <td valign="top"> Introduzione alla rete</td> 
                  <td valign="top"> Introduzione alla rete</td> 
-                 <td valign="top"> completi, da revisionare </td>
+                 <td valign="top"> completo, da revisionare </td>
+               </tr>
+               <tr>
+                 <td valign="top"> <b> Cap. 14 </b> </td>
+                 <td valign="top"> I socket</td> 
+                 <td valign="top"> completo, da revisionare. Manca la
+                 trattazione di eventuali ulteriori famiglie. </td>
                </tr>
                <tr>
                  <td valign="top"> <b> Cap. 15-16 </b> </td>
                </tr>
                <tr>
                  <td valign="top"> <b> Cap. 15-16 </b> </td>
-                 <td valign="top"> Socket TCP elementari</td> 
-                 <td valign="top"> Caratteristiche base quasi complete,
-                   esempio elementare da concludere </td>
+                 <td valign="top"> I socket TCP </td> 
+                 <td valign="top"> socket TCP elementari completo, da
+                   revisionare. Socket TCP avanzati appena iniziato,
+                   in fase di stesura.
+
+                 </td>
+               </tr>
+               <tr>
+                 <td valign="top"> <b> Appendici </b> </td>
+                 <td valign="top"> I protocolli, gli errori, ecc.</td> 
+                 <td valign="top"> Materiale messo insieme alla
+                 rinfusa, e da rivedere da zero.
+                 </td>
                </tr>
              </tbody>
            </table>
            <p>
                </tr>
              </tbody>
            </table>
            <p>
-             <b> Versione corrente:</b> 473 pagine.
+             <b> Versione corrente:</b> 485 pagine.
            </p>
          </td>
        </tr>
            </p>
          </td>
        </tr>
            </b>
          </td>
          <td bgcolor="lightblue"> 
            </b>
          </td>
          <td bgcolor="lightblue"> 
+
+             <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>
              <b>6 - aprile - 2003</b> <br/> Grazie all'incredibile lavoro di
              Mirko Maischberger abbiamo una favolosa versione in HTML, che
            <p>
              <b>6 - aprile - 2003</b> <br/> Grazie all'incredibile lavoro di
              Mirko Maischberger abbiamo una favolosa versione in HTML, che
index 63b97438411db9afb5dc08415f464f0948f2b53b..ae53fd0d1dc7585b0451710636820d80484c0772 100644 (file)
@@ -221,7 +221,7 @@ chiusura attiva.  Nella sequenza indicata i dati verrebbero persi, dato che si
 è chiuso il socket dal lato che esegue la chiusura attiva; esistono tuttavia
 situazioni in cui si vuole poter sfruttare questa possibilità, usando una
 procedura che è chiamata \textit{half-close}; torneremo su questo aspetto e su
 è chiuso il socket dal lato che esegue la chiusura attiva; esistono tuttavia
 situazioni in cui si vuole poter sfruttare questa possibilità, usando una
 procedura che è chiamata \textit{half-close}; torneremo su questo aspetto e su
-come utilizzarlo in \secref{xxx_shutdown}, quando parleremo della funzione
+come utilizzarlo in \secref{sec:TCP_shutdown}, quando parleremo della funzione
 \func{shutdown}.
 
 La emissione del FIN avviene quando il socket viene chiuso, questo però non
 \func{shutdown}.
 
 La emissione del FIN avviene quando il socket viene chiuso, questo però non
@@ -339,8 +339,8 @@ La MSL 
 sulla rete; questo tempo è limitato perché ogni pacchetto IP può essere
 ritrasmesso dai router un numero massimo di volte (detto \textit{hop limit}).
 Il numero di ritrasmissioni consentito è indicato dal campo TTL dell'header di
 sulla rete; questo tempo è limitato perché ogni pacchetto IP può essere
 ritrasmesso dai router un numero massimo di volte (detto \textit{hop limit}).
 Il numero di ritrasmissioni consentito è indicato dal campo TTL dell'header di
-IP (per maggiori dettagli vedi \secref{sec:IP_xxx}), e viene decrementato ad
-ogni passaggio da un router; quando si annulla il pacchetto viene scartato.
+IP (per maggiori dettagli vedi \secref{sec:ip_protocol}), e viene decrementato
+ad ogni passaggio da un router; quando si annulla il pacchetto viene scartato.
 Siccome il numero è ad 8 bit il numero massimo di ``\textsl{salti}'' è di 255,
 pertanto anche se il TTL (da \textit{time to live}) non è propriamente un
 limite sul tempo di vita, si stima che un pacchetto IP non possa restare nella
 Siccome il numero è ad 8 bit il numero massimo di ``\textsl{salti}'' è di 255,
 pertanto anche se il TTL (da \textit{time to live}) non è propriamente un
 limite sul tempo di vita, si stima che un pacchetto IP non possa restare nella
@@ -1034,8 +1034,8 @@ funzione.  Se non ci sono connessioni pendenti da accettare la funzione mette
 in attesa il processo\footnote{a meno che non si sia impostato il socket per
   essere non bloccante (vedi \secref{sec:file_noblocking}), nel qual caso
   ritorna con l'errore \errcode{EAGAIN}.  Torneremo su questa modalità di
 in attesa il processo\footnote{a meno che non si sia impostato il socket per
   essere non bloccante (vedi \secref{sec:file_noblocking}), nel qual caso
   ritorna con l'errore \errcode{EAGAIN}.  Torneremo su questa modalità di
-  operazione in \secref{sec:xxx_sock_noblock}.}  fintanto che non ne arriva
-una.
+  operazione in \secref{sec:TCP_sock_multiplexing}.}  fintanto che non ne
+arriva una.
 
 La funzione può essere usata solo con socket che supportino la connessione
 (cioè di tipo \const{SOCK\_STREAM}, \const{SOCK\_SEQPACKET} o
 
 La funzione può essere usata solo con socket che supportino la connessione
 (cioè di tipo \const{SOCK\_STREAM}, \const{SOCK\_SEQPACKET} o
@@ -1202,7 +1202,7 @@ si aspetta in una qualunque applicazione client/server.
 Per attivare immediatamente l'emissione del FIN e la sequenza di chiusura
 descritta in \secref{sec:TCP_conn_term}, si può invece usare la funzione
 \func{shutdown} su cui torneremo in seguito (vedi
 Per attivare immediatamente l'emissione del FIN e la sequenza di chiusura
 descritta in \secref{sec:TCP_conn_term}, si può invece usare la funzione
 \func{shutdown} su cui torneremo in seguito (vedi
-\secref{sec:TCP_xxx_shutdown}).
+\secref{sec:TCP_shutdown}).
 
 
 
 
 
 
@@ -2384,7 +2384,7 @@ definitiva della connessione anche nel client, dove non comparir
 nell'output di \cmd{netstat}.
 
 Come abbiamo accennato in \secref{sec:TCP_conn_term} e come vedremo più avanti
 nell'output di \cmd{netstat}.
 
 Come abbiamo accennato in \secref{sec:TCP_conn_term} e come vedremo più avanti
-in \secref{sec:TCP_xxx_shutdown} la chiusura di un solo capo di un socket è
+in \secref{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 parametro 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 parametro un
@@ -2657,7 +2657,8 @@ riportando appunto come errore \errcode{ECONNRESET}. Occorre precisare che se
 si vuole che il client sia in grado di accorgersi del crollo del server anche
 quando non sta effettuando uno scambio di dati, è possibile usare una
 impostazione speciale del socket (ci torneremo in
 si vuole che il client sia in grado di accorgersi del crollo del server anche
 quando non sta effettuando uno scambio di dati, è possibile usare una
 impostazione speciale del socket (ci torneremo in
-\secref{sec:TCP_xxx_sockopt}) che provvede all'esecuzione di questo controllo.
+\secref{sec:TCP_sock_options}) che provvede all'esecuzione di questo
+controllo.
 
 
 
 
 
 
index 81c37eb5bc981d8f912ea56cdb414f7e10634040..24c45d2cbf9d1aa707fec08f248fbb4e5703530e 100644 (file)
@@ -35,25 +35,103 @@ riprenderemo l'argomento in questa sezione.
 
 
 
 
 
 
-\subsection{La funzione \func{select} con i socket.}
+\subsection{Il comportamento della funzione \func{select} con i socket.}
 \label{sec:TCP_sock_select}
 
 \label{sec:TCP_sock_select}
 
-
-
-
 Iniziamo con la prima delle funzioni usate per l'I/O multiplexing,
 \func{select}, il suo funzionamento è già stato descritto in dettaglio in
 Iniziamo con la prima delle funzioni usate per l'I/O multiplexing,
 \func{select}, il suo funzionamento è già stato descritto in dettaglio in
-\secref{sec:file_multiplexing}; e sappiamo che la funzione ritorna quando uno
-o più dei file descriptor messi sotto controllo è pronto per la relativa
-operazione. 
+\secref{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.
 
 In quell'occasione non abbiamo però definito cosa si intende per pronto,
 
 In quell'occasione non abbiamo però definito cosa si intende per pronto,
-infatti se per dei normali file, o anche per delle pipe, la condizione di
-essere pronti per la lettura o la scrittura è ovvia, lo è un po' meno di meno
-nel caso dei socket, visto che intervengono tutte le possibili condizioni
-dovute alla rete. Occorre allora specificare quali sono le condizioni in cui
-un socket risulta \textsl{pronto}.
-
+infatti per dei normali file, o anche per delle pipe, la condizione di essere
+pronti per la lettura o la scrittura è ovvia, lo è un po' meno di meno nel
+caso dei socket, visto che intervengono tutte le possibili condizioni dovute
+alla rete. Occorre allora specificare quali sono le condizioni in cui un
+socket risulta \textsl{pronto} quando viene passato come membro di uno dei tre
+\textit{file descriptor set} usati da \func{select}.
+
+Le condizioni che fanno si che la funzione \func{select} ritorni segnalando
+che un socket (che sarà riportato nel primo insieme di file descriptor) è
+pronto per la lettura sono le seguenti:
+\begin{itemize*}
+\item nel buffer di ricezione del socket sono arrivati dei dati in quantità
+  sufficiente a superare il valore di una \textsl{soglia di basso livello} (il
+  cosiddetto \textit{low watermark}). Questo valore è espresso in numero di
+  byte e può essere impostato con l'opzione del socket \const{SO\_RCVLOWAT}
+  (tratteremo le opzioni dei socket in \secref{sec:TCP_sock_options}); il suo
+  valore di default è 1 per i socket TCP e UDP. In questo caso una operazione
+  di lettura avrà successo e leggerà un numero di byte maggiore di zero.
+\item il lato in lettura della connessione è stato chiuso; si è cioè ricevuto
+  un segmento FIN (si ricordi quanto illustrato in \secref{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.
+\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
+  valore. Vedremo in \secref{sec:TCP_sock_options} come sia possibile estrarre
+  e cancellare errori pendenti su un socket usando l'opzione
+  \const{SO\_ERROR}.
+\item quando si sta utilizzando un \textit{listening socket} ed ci sono delle
+  connessioni completate. In questo caso la funzione \func{accept} non si
+  bloccherà.\footnote{in realtà questo non è sempre vero, come accennato in
+    \secref{sec:TCP_conn_early_abort} una connessione può essere abortita
+    dalla ricezione di un segmento RST una volta che è stata completata,
+    allora se questo avviene dopo che \func{select} è ritornata, ma prima
+    della chiamata ad \func{accept} quest'ultima, in assenza di altre
+    connessiioni, potrà bloccarsi.}
+\end{itemize*}
+
+Le condizioni che fanno si che la funzione \func{select} ritorni segnalando
+che un socket (che sarà riportato nel secondo insieme di file descriptor) è
+pronto per la scrittura sono le seguenti:
+\begin{itemize*}
+\item nel buffer di invio è disponibile una quantità di spazio superiore al
+  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}; 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
+  dal livello di trasporto.
+\item il lato in scrittura della connessione è stato chiuso. In questo caso
+  una operazione di scrittura sul socket genererà il segnale \const{SIGPIPE}.
+\item c'è stato un errore sul socket. In questo caso una operazione di
+  scrittura non si bloccherà ma restituirà una condizione di errore ed
+  imposterà opportunamente la variabile \var{errno}. Vedremo in
+  \secref{sec:TCP_sock_options} come sia possibile estrarre e cancellare
+  errori pendenti su un socket usando l'opzione \const{SO\_ERROR}.
+\end{itemize*}
+
+Infine c'è una sola condizione che fa si che \func{select} ritorni segnalando
+che un socket (che sarà riportato nel terzo insieme di file descriptor) ha una
+condizione di eccezione pendente, e cioè la ricezione sul socket di dati
+\textsl{fuori banda} (o \textit{out-of-band}), una caratteristica specifica
+dei socket TCP su cui torneremo in \secref{sec:TCP_outofband}.
+
+Si noti come nel caso della lettura \func{select} si applichi anche ad
+operazioni che non hanno nulla a che fare con l'I/O come il riconoscimento
+della presenza di connessioni pronte, in modo da consentire l'utilizzo di
+\func{accept} in modalità non bloccante. Si noti infine come in caso di errore
+un socket venga sempre riportato come pronto sia per la lettura che per la
+scrittura.
+
+Lo scopo dei due valori di soglia per i buffer di ricezione e di invio è
+quello di consentire maggiore flessibilità nell'uso di \func{select} da parte
+dei programmi, se infatti si sa che una applicazione non è in grado di fare
+niente fintanto che non può ricevere o inviare una certa quantità di dati, si
+possono utilizzare questi valori per far si che \func{select} ritorni solo
+quando c'è la certezza di avere dati a sufficienza.\footnote{questo tipo di
+  controllo è utile di norma solo per la lettura, in quanto in genere le
+  operazioni di scrittura sono già controllate dall'applicazione, che sà
+  sempre quanti dati invia, mentre non è detto possa conoscere la quantità di
+  dati in ricezione; per cui, nella situazione in cui si conosce almeno un
+  valore minimo, per evitare la penalizzazione dovuta alla ripetizione delle
+  operazioni di lettura quando per accumulare dati sufficienti, si può
+  lasciare al kernel il compito di impostare un minimo al di sotto del quale
+  il file descriptor, pur avendo disponibili dei dati, non viene letto.}
 
 
 
 
 
 
@@ -62,8 +140,9 @@ un socket risulta \textsl{pronto}.
 \label{sec:TCP_sock_options}
 
 Dato che la maggior parte delle opzioni dei socket sono relative ai socket
 \label{sec:TCP_sock_options}
 
 Dato che la maggior parte delle opzioni dei socket sono relative ai socket
-TCP, ed hanno poi significato analogo quando usate con altri socket,
-tratteremo qui l'argomento in generale.
+TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
+preferito trattare l'argomento in generale in questa sezione piuttosto che
+nel capitolo dedicato alla trattazione generica dei socket.