Cambiato il riferimento nelle note di copyright alla nuova sezione invariante
[gapil.git] / othersock.tex
index d73aa57b5328364ab5ed84531873f1fb2cccf044..dcf4ee588adb8d23e9ab24aa5d8837166e276e06 100644 (file)
@@ -3,7 +3,7 @@
 %% Copyright (C) 2004 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
-%% Free Software Foundation; with the Invariant Sections being "Prefazione",
+%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
 %% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
@@ -14,7 +14,7 @@
 Dopo aver trattato in cap.~\ref{cha:TCP_socket} i socket TCP, che costituiscono
 l'esempio più comune dell'interfaccia dei socket, esamineremo in questo
 capitolo gli altri tipi di socket, a partire dai socket UDP, e i socket
-\textit{Unix domain} già incontrati in \secref{sec:ipc_socketpair}.
+\textit{Unix domain} già incontrati in sez.~\ref{sec:ipc_socketpair}.
 
 
 \section{I socket UDP}
@@ -264,9 +264,10 @@ I due argomenti \param{from} e \param{fromlen} sono utilizzati per ottenere
 l'indirizzo del mittente del pacchetto che è stato ricevuto, e devono essere
 opportunamente inizializzati con i puntatori alle variabili dove la struttura
 contenente quest'ultimo e la relativa lunghezza saranno scritti (si noti che
-\param{fromlen} è un valore intero ottenuto come \textit{value return
-  argument}).  Se non si è interessati a questa informazione, entrambi gli
-argomenti devono essere inizializzati al valore \const{NULL}.
+\param{fromlen} è un valore intero ottenuto come
+\index{\textit{value~result~argument}}\textit{value result argument}).  Se non
+si è interessati a questa informazione, entrambi gli argomenti devono essere
+inizializzati al valore \const{NULL}.
 
 Una differenza fondamentale del comportamento di queste funzioni rispetto alle
 usuali \func{read} e \func{write} che abbiamo usato con i socket TCP è che in
@@ -519,7 +520,7 @@ per
 \begin{figure}[!htb] 
   \footnotesize \centering
   \begin{minipage}[c]{15.6cm}
-    \includecodesample{listati/UDP_ClientEcho.c}
+    \includecodesample{listati/UDP_ClientEcho_first.c}
   \end{minipage}
   \normalsize
   \caption{Codice della funzione \func{ClientEcho} usata dal client per il
@@ -656,8 +657,8 @@ 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
+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
@@ -666,17 +667,18 @@ le normali funzioni \func{read} e \func{write}.\footnote{in realt
   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
+Una volta che il socket è connesso cambia però 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. 
+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}.
+Infine quando si usa un socket connesso, 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 esso; pertanto potremo
+riscrivere il nostro client per il servizio \textit{echo} con le modifiche
+illustrate in fig.~\ref{fig:UDP_echo_conn_cli}.
 
 \begin{figure}[!htb] 
   \footnotesize \centering
@@ -684,27 +686,71 @@ modifiche illustrate in fig.~\ref{fig:UDP_echo_conn_cli}.
     \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.}
+  \caption{Seconda versione del client del servizio \textit{echo} che utilizza
+    socket UDP connessi.}
   \label{fig:UDP_echo_conn_cli}
 \end{figure}
 
+Ed in questo caso rispetto alla precedente versione, il solo cambiamento è
+l'utilizzo (\texttt{\small 17}) della funzione \func{connect} prima della
+chiamata alla funzione di gestione del protocollo, che a sua volta è stata
+modificata eliminando l'indirizzo passato come parametro e sostituendo le
+chiamata a \func{sendto} e \func{recvfrom} con chiamate a \func{read} e
+\func{write} come illustrato dal nuovo codice riportato in
+fig.~\ref{fig:UDP_echo_conn_echo_client}.
+
+\begin{figure}[!htb] 
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/UDP_ClientEcho.c}
+  \end{minipage}
+  \normalsize
+  \caption{Seconda versione della funzione \func{ClientEcho}.}
+  \label{fig:UDP_echo_conn_echo_client}
+\end{figure}
+
+Utilizzando questa nuova versione del client si può verificare che quando ci
+si rivolge verso un indirizzo inesistente o su cui non è in ascolto un server
+si è in grado rilevare l'errore, se infatti eseguiamo il nuovo programma
+otterremo un qualcosa del tipo:
+\begin{verbatim}
+[piccardi@gont sources]$ ./echo 192.168.1.1
+prova
+Errore in lettura: Connection refused
+\end{verbatim}%$
+
+Ma si noti che a differenza di quanto avveniva con il client TCP qui l'errore
+viene rilevato soltanto dopo che si è tentato di inviare qualcosa, ed in
+corrispondenza al tentativo di lettura della risposta. Questo avviene perché
+con UDP non esiste una connessione, e fintanto che non si invia un pacchetto
+non c'è traffico sulla rete. In questo caso l'errore sarà rilevato alla
+ricezione del pacchetto ICMP \textit{destination unreachable} emesso dalla
+macchina cui ci si è rivolti, e questa volta, essendo il socket UDP connesso,
+il kernel potrà riportare detto errore in user space in maniera non ambigua,
+ed esso apparirà alla successiva lettura sul socket.
+
+Si tenga presente infine che l'uso dei socket connessi non risolve l'altro
+problema del client, e cioè il fatto che in caso di perdita di un pacchetto
+questo resterà bloccato permanentemente in attesa di una risposta. Per
+risolvere questo problema l'unico modo sarebbe quello di impostare un
+\textit{timeout} o riscrivere il client in modo da usare l'I/O non bloccante.
 
 
 
 \section{I socket \textit{Unix domain}}
 \label{sec:unix_socket}
 
-Benché i socket Unix domain non siano strettamente attinenti alla rete, in
-quanto definiscono una interfaccia di comunicazione locale alla singola
-macchina, li tratteremo comunque in questa sezione in quanto la loro
-interfaccia è comunque basata sulla più generale interfaccia dei socket.
+Benché i socket Unix domain, come meccanismo di comunicazione fra processi che
+girano sulla stessa macchina, non siano strettamente attinenti alla rete, li
+tratteremo comunque in questa sezione. Nonstante le loro peculiarità infatti,
+l'interfaccia di programmazione che serve ad utilizzarli resta sempre quella
+dei socket.
+
 
 
 \section{Altri socket}
 \label{sec:socket_other}
 
-
 Tratteremo in questa sezione gli altri tipi particolari di socket supportati
 da Linux, come i \textit{raw socket}, con i quali si possono \textsl{forgiare}
 direttamente i pacchetti a tutti i livelli dello stack dei protocolli, o i