Ultimo materiale, rivisto HTML del sito, e iniziato a parlare di select +
[gapil.git] / tcpsockadv.tex
index 3ac534820006db9fef38c576874a318f6ae2f162..24c45d2cbf9d1aa707fec08f248fbb4e5703530e 100644 (file)
@@ -1,4 +1,4 @@
-%% tcpsockadv.tex
+ %% tcpsockadv.tex
 %%
 %% Copyright (C) 2003 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
@@ -17,9 +17,122 @@ socket TCP.
 
 
 \section{Socket multiplexing}
-\label{sec:TCP_sock_mutiplexing}
+\label{sec:TCP_sock_multiplexing}
+
+Affronteremo in questa sezione l'utilizzo dell'I/O multiplexing, affrontato in
+\secref{sec:file_multiplexing}, nell'ambito delle applicazioni di rete. Già in
+\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.
+
+Abbiamo visto in \secref{sec:file_multiplexing} quali sono le funzionalità del
+sistema che ci permettono di tenere sotto controllo più file descriptor in
+contemporanea; in quella occasione non abbiamo fatto esempi, in quanto quando
+si tratta con file normali questa tipologia di I/O non viene usata, è invece
+un caso tipico delle applicazioni di rete quello di dover gestire varie
+connessioni da cui possono arrivare dati comuni in maniera 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,
+\func{select}, il suo funzionamento è già stato descritto in dettaglio in
+\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,
+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.}
 
-Affronteremo in questa sezione l'utilizzo dei socket 
 
 
 
@@ -27,8 +140,9 @@ Affronteremo in questa sezione l'utilizzo dei 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.