Inserita una nota esplicativa sulla struttura dirent, su segnalazione di
[gapil.git] / othersock.tex
index 7897c6eb27d4e27b92cd990a7674cd422f9c265b..d73aa57b5328364ab5ed84531873f1fb2cccf044 100644 (file)
@@ -498,11 +498,11 @@ possono avere proviamo allora con un servizio leggermente pi
 \begin{figure}[!htb] 
   \footnotesize \centering
   \begin{minipage}[c]{15.6cm}
-    \includecodesample{listati/UDP_echo.c}
+    \includecodesample{listati/UDP_echo_first.c}
   \end{minipage} 
   \normalsize
-  \caption{Sezione principale del client per il servizio \textit{echo} su
-    UDP.}
+  \caption{Sezione principale della prima versione client per il servizio
+    \textit{echo} su UDP.}
   \label{fig:UDP_echo_client}
 \end{figure}
 
@@ -524,11 +524,11 @@ per
   \normalsize
   \caption{Codice della funzione \func{ClientEcho} usata dal client per il
     servizio \textit{echo} su UDP.}
-  \label{fig:UDP_echo_clientecho}
+  \label{fig:UDP_echo_client_echo}
 \end{figure}
 
 Ovviamente in questo caso il funzionamento della funzione, il cui codice è
-riportato in fig.~\ref{fig:UDP_echo_clientecho}, è completamente diverso
+riportato in fig.~\ref{fig:UDP_echo_client_echo}, è completamente diverso
 rispetto alla analoga del server TCP, e dato che non esiste una connessione
 questa necessita anche di un terzo argomento, che è l'indirizzo del server cui
 inviare i pacchetti.
@@ -617,25 +617,31 @@ irraggiungibile che ci segnala che la porta in questione non risponde.
 Ci si può chiedere allora perché, benché la situazione di errore sia
 rilevabile, questa non venga segnalata. Il luogo più naturale in cui
 riportarla sarebbe la chiamata di \func{sendto}, in quanto è a causa dell'uso
-di indirizzo sbagliato che il pacchetto non può essere inviato; farlo in
+di un indirizzo sbagliato che il pacchetto non può essere inviato; farlo in
 questo punto però è impossibile, dato che l'interfaccia di programmazione
-richiede che la funzione ritorni non appena il kernel invia il pacchetto, e
-non può bloccarsi in una attesa di una risposta che potrebbe essere molto
-lunga (si noti infatti che il pacchetto ICMP arriva qualche decimo di secondo
-più tardi) o non esserci affatto.  
+richiede che la funzione ritorni non appena il kernel invia il
+pacchetto,\footnote{questo è il classico caso di \textsl{errore asincrono},
+  una situazione cioè in cui la condizione di errore viene rilevata in maniera
+  asincrona rispetto all'operazione che l'ha causata, una eventualità
+  piuttosto comune quando si ha a che fare con la rete, tutti i pacchetti ICMP
+  che segnalano errori rientrano in questa tipologia.} e non può bloccarsi in
+una attesa di una risposta che potrebbe essere molto lunga (si noti infatti
+che il pacchetto ICMP arriva qualche decimo di secondo più tardi) o non
+esserci affatto.
 
 Si potrebbe allora pensare di riportare l'errore nella \func{recvfrom} che è
-comunque bloccata in attesa di una risposta che nel caso non non arriverà mai.
-La ragione di tutto questo è piuttosto sottile e viene trattata da Stevens in
-\cite{UNP2} con il seguente esempio: si consideri un client che invia tre
-pacchetti a tre diverse macchine, due quali vengono regolarmente ricevuti,
-mentre al terzo, non essendo presente un server sulla relativa macchina, viene
-risposto con un messaggio ICMP come il precedente. Detto messaggio conterrà
-anche le informazioni relative ad indirizzo e porta del pacchetto che ha
-fallito, però tutto quello che il kernel può restituire al programma è un
-codice di errore in \var{errno}, e pertanto è stata fatta la scelta di non
-riportare l'errore, a meno che, come vedremo in sez.~\ref{sec:UDP_connect}, il
-socket non sia connesso.
+comunque bloccata in attesa di una risposta che nel caso non arriverà mai.  La
+ragione per cui non viene fatto è piuttosto sottile e viene spiegata da
+Stevens in \cite{UNP2} con il seguente esempio: si consideri un client che
+invia tre pacchetti a tre diverse macchine, due dei quali vengono regolarmente
+ricevuti, mentre al terzo, non essendo presente un server sulla relativa
+macchina, viene risposto con un messaggio ICMP come il precedente. Detto
+messaggio conterrà anche le informazioni relative ad indirizzo e porta del
+pacchetto che ha fallito, però tutto quello che il kernel può restituire al
+programma è un codice di errore in \var{errno}, con il quale è impossibile di
+distinguere per quale dei pacchetti inviati si è avuto l'errore; per questo è
+stata fatta la scelta di non riportare un errore su un socket UDP, a meno che,
+come vedremo in sez.~\ref{sec:UDP_connect}, questo non sia connesso.
 
 
 
@@ -644,7 +650,45 @@ socket non sia connesso.
 
 Come illustrato in sez.~\ref{sec:UDP_characteristics} essendo i socket UDP
 privi di connessione non è necessario per i client usare \func{connect} prima
-di iniziare una comunicazione con un server.
+di iniziare una comunicazione con un server. Ciò non di meno abbiamo accennato
+come questa possa essere utilizzata per gestire la presenza di errori
+asincroni.
+
+Quando si chiama \func{connect} su di un socket UDP tutto quello che succede è
+che l'indirizzo passato alla funzione viene registrato come indirizzo di
+destinazione del socket, a differenza di quanto avviene con TCP non viene
+scambiato nessun pacchetto; tutto quello che succede è che da quel momento in
+qualunque cosa si scriva sul socket sarà inviata a quell'indirizzo; non sarà
+più necessario usare l'argomento \param{to} di \func{sendto} per specificare
+la destinazione dei pacchetti, che potranno essere inviati e ricevuti usando
+le normali funzioni \func{read} e \func{write}.\footnote{in realtà si può
+  anche continuare ad usare la funzione \func{sendto}, ma in tal caso
+  l'argomento \param{to} deve essere inizializzato a \const{NULL}, e
+  \param{tolen} deve essere inizializzato a zero, pena un errore.}
+
+Una volta che il socket è connesso però cambia anche il comportamento in
+ricezione; prima infatti il kernel avrebbe restituito al socket qualunque
+pacchetto ricevuto con un indirizzo di destinazione corrispondente a quello
+del socket, senza nessun controllo sulla sorgente; una volta che il socket
+viene connesso saranno riportati su di esso solo i pacchetti con un indirizzo
+sorgente corrispondente a quello a cui ci si è connessi. 
+
+Infine quando si è connesso un socket, venendo meno l'ambiguità segnalata alla
+fine di sez.~\ref{sec:UDP_problems}, tutti gli eventuali errori asincroni
+vengono riportati alle funzioni che operano su di esse, pertanto con le
+modifiche illustrate in fig.~\ref{fig:UDP_echo_conn_cli}.
+
+\begin{figure}[!htb] 
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/UDP_echo.c}
+  \end{minipage}
+  \normalsize
+  \caption{Nuova sezione della seconda versione del client del servizio
+    \textit{echo} che utilizza socket UDP connessi.}
+  \label{fig:UDP_echo_conn_cli}
+\end{figure}
+