Cambiato il riferimento nelle note di copyright alla nuova sezione invariante
[gapil.git] / othersock.tex
index 3a64aa794a8231c7b467cd7e6b536805f533df06..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".
 \chapter{Gli altri tipi di socket}
 \label{cha:other_socket}
 
-Dopo aver trattato in \capref{cha:TCP_socket} i socket TCP, che costituiscono
+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}
@@ -29,10 +29,10 @@ principali e le modalit
 \subsection{Le caratteristiche di un socket UDP}
 \label{sec:UDP_characteristics}
 
-Come illustrato in \secref{sec:net_udp} UDP è un protocollo molto semplice che
+Come illustrato in sez.\ref{sec:net_udp} UDP è un protocollo molto semplice che
 non supporta le connessioni e non è affidabile: esso si appoggia direttamente
-sopra IP (per i dettagli sul protocollo si veda \secref{sec:udp_protocol}).  I
-dati vengono inviati in forma di pacchetti, e non ne è assicurata né la
+sopra IP (per i dettagli sul protocollo si veda sez.~\ref{sec:udp_protocol}).
+dati vengono inviati in forma di pacchetti, e non ne è assicurata né la
 effettiva ricezione né l'arrivo nell'ordine in cui vengono inviati. Il
 vantaggio del protocollo è la velocità, non è necessario trasmettere le
 informazioni di controllo ed il risultato è una trasmissione di dati più
@@ -48,16 +48,16 @@ Questo diverso comportamento significa anche che i socket UDP, pur
 appartenendo alla famiglia \const{PF\_INET}\footnote{o \const{PF\_INET6}
   qualora si usasse invece il protocollo IPv6, che pure supporta UDP.} devono
 essere aperti quando si usa la funzione \func{socket} (si riveda quanto
-illustrato a suo tempo in \tabref{tab:sock_sock_valid_combinations})
+illustrato a suo tempo in tab.~\ref{tab:sock_sock_valid_combinations})
 utilizzando per il tipo di socket il valore \const{SOCK\_DGRAM}.
 
 Questa differenza comporta ovviamente che anche le modalità con cui si usano i
 socket UDP sono completamente diverse rispetto ai socket TCP, ed in
 particolare non esistendo il concetto di connessione non esiste il meccanismo
-del \textit{three way handshake} nè quello degli stati del protocollo. In
+del \textit{three way handshake} né quello degli stati del protocollo. In
 realtà tutto quello che avviene nella comunicazione attraverso dei socket UDP
 è la trasmissione di un pacchetto da un client ad un server o viceversa,
-secondo lo schema illustrato in \figref{fig:UDP_packet-exchange}.
+secondo lo schema illustrato in fig.~\ref{fig:UDP_packet-exchange}.
 
 \begin{figure}[htb]
   \centering
@@ -67,17 +67,17 @@ secondo lo schema illustrato in \figref{fig:UDP_packet-exchange}.
   \label{fig:UDP_packet-exchange}
 \end{figure}
 
-Come illustrato in \figref{fig:UDP_packet-exchange} la struttura generica di
+Come illustrato in fig.~\ref{fig:UDP_packet-exchange} la struttura generica di
 un server UDP prevede, una volta creato il socket, la chiamata a \func{bind}
 per mettersi in ascolto dei dati. Questa è l'unica parte comune con un server
 TCP: non essendovi il concetto di connessione le funzioni \func{listen} ed
 \func{accept} non sono mai utilizzate nel caso di server UDP. La ricezione dei
 dati dal client avviene attraverso la funzione \func{recvfrom}, mentre una
-eventuale risposta sarà inviata con la funzione \func{sendto}. 
+eventuale risposta sarà inviata con la funzione \func{sendto}.
 
 Da parte del client invece, una volta creato il socket non sarà necessario
 connettersi con \func{connect} (anche se, come vedremo in
-\secref{sec:UDP_connect}, è possibile usare questa funzione, con un
+sez.~\ref{sec:UDP_connect}, è possibile usare questa funzione, con un
 significato comunque diverso) ma si potrà effettuare direttamente una
 richiesta inviando un pacchetto con la funzione \func{sendto} e si potrà
 leggere una eventuale risposta con la funzione \func{recvfrom}.
@@ -113,19 +113,19 @@ destinati, oppure a scartarli inviando un messaggio \textit{ICMP port
 \subsection{Le funzioni \func{sendto} e \func{recvfrom}}
 \label{sec:UDP_sendto_recvfrom}
 
-Come accennato in \secref{sec:UDP_characteristics} le due funzioni principali
-usate per la trasmissione di dati attraverso i socket UDP sono \func{sendto} e
-\func{recvfrom}. La necessità di usare queste funzioni è dovuta al fatto che
-non esistendo con UDP il concetto di connessione, non si ha neanche a
-disposizione un \textsl{socket connesso} su cui sia possibile usare
-direttamente \func{read} e \func{write} avendo già stabilito (grazie alla
-chiamata ad \func{accept} che lo associa ad una connessione) quali sono
+Come accennato in sez.~\ref{sec:UDP_characteristics} le due funzioni
+principali usate per la trasmissione di dati attraverso i socket UDP sono
+\func{sendto} e \func{recvfrom}. La necessità di usare queste funzioni è
+dovuta al fatto che non esistendo con UDP il concetto di connessione, non si
+ha neanche a disposizione un \textsl{socket connesso} su cui sia possibile
+usare direttamente \func{read} e \func{write} avendo già stabilito (grazie
+alla chiamata ad \func{accept} che lo associa ad una connessione) quali sono
 sorgente e destinazione dei dati.
 
 Per questo motivo nel caso di UDP diventa essenziale utilizzare queste due
 funzioni, che sono comunque utilizzabili in generale per la trasmissione di
 dati attraverso qualunque tipo di socket. Esse hanno la caratteristica di
-prevedere tre argomenti aggiuntivi attraveso i quali è possibile specificare
+prevedere tre argomenti aggiuntivi attraverso i quali è possibile specificare
 la destinazione dei dati trasmessi o ottenere l'origine dei dati ricevuti. La
 prima di queste funzioni è \funcd{sendto} ed il suo prototipo\footnote{il
   prototipo illustrato è quello utilizzato dalle \acr{glibc}, che seguono le
@@ -149,9 +149,9 @@ prima di queste funzioni 
     rispettivo codice di errore:
   \begin{errlist}
   \item[\errcode{EAGAIN}] il socket è in modalità non bloccante, ma
-    l'operazione richede che la funzione si blocchi.
+    l'operazione richiede che la funzione si blocchi.
   \item[\errcode{ECONNRESET}] l'altro capo della comunicazione ha resettato la
-    conessione.
+    connessione.
   \item[\errcode{EDESTADDRREQ}] il socket non è di tipo connesso, e non si è
     specificato un indirizzo di destinazione.
   \item[\errcode{EISCONN}] il socket è già connesso, ma si è specificato un
@@ -189,9 +189,9 @@ fallisce con l'errore di \errcode{EMSGSIZE}.
 
 I due argomenti \param{to} e \param{tolen} servono a specificare la
 destinazione del messaggio da inviare, e indicano rispettivamente la struttura
-contentente l'indirizzo di quest'ultima e la sua dimensione; questi argomenti
+contenente l'indirizzo di quest'ultima e la sua dimensione; questi argomenti
 vanno specificati stessa forma in cui li si sarebbero usati con
-\func{connect}. Nel nostro caso \param{to} devrà puntare alla struttura
+\func{connect}. Nel nostro caso \param{to} dovrà puntare alla struttura
 contenente l'indirizzo IP e la porta di destinazione verso cui si vogliono
 inviare i dati (questo è indifferente rispetto all'uso di TCP o UDP, usando
 socket diversi si sarebbero dovute utilizzare le rispettive strutture degli
@@ -201,8 +201,8 @@ Se il socket 
 TCP), questo deve essere già connesso prima di poter eseguire la funzione, in
 caso contrario si riceverà un errore di \errcode{ENOTCONN}. In questo
 specifico caso in cui gli argomenti \param{to} e \param{tolen} non servono
-essi devranno essere inizializzati rispettivamente a \const{NULL} e 0;
-normalmente quando si opera su un socket conesso essi vengono ignorati, ma
+essi dovranno essere inizializzati rispettivamente a \const{NULL} e 0;
+normalmente quando si opera su un socket connesso essi vengono ignorati, ma
 qualora si sia specificato un indirizzo è possibile ricevere un errore di
 \errcode{EISCONN}.
 
@@ -211,9 +211,9 @@ come maschera binaria che permette di impostare una serie di modalit
 funzionamento della comunicazione attraverso il socket (come
 \const{MSG\_NOSIGNAL} che impedisce l'invio del segnale \const{SIGPIPE} quando
 si è già chiuso il capo locale della connessione). Torneremo con maggiori
-dettagli sul significato di questo argomento in \secref{sec:xxx_sendmsg}, dove
-tratteremo le funzioni avanzate dei socket, per il momento ci si può limitare
-ad usare sempre un valore nullo.
+dettagli sul significato di questo argomento in sez.~\ref{sec:xxx_sendmsg},
+dove tratteremo le funzioni avanzate dei socket, per il momento ci si può
+limitare ad usare sempre un valore nullo.
 
 La seconda funzione utilizzata nella comunicazione fra socket UDP è
 \funcd{recvfrom}, che serve a ricevere i dati inviati da un altro socket; il
@@ -237,7 +237,7 @@ suo prototipo\footnote{il prototipo 
     valore:
   \begin{errlist}
   \item[\errcode{EAGAIN}] il socket è in modalità non bloccante, ma
-    l'operazione richede che la funzione si blocchi, oppure si è impostato un
+    l'operazione richiede che la funzione si blocchi, oppure si è impostato un
     timeout in ricezione e questo è scaduto.
   \item[\errcode{ECONNREFUSED}] l'altro capo della comunicazione ha rifiutato
     la connessione (in genere perché il relativo servizio non è disponibile).
@@ -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
-  argoment}).  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
@@ -277,7 +278,7 @@ ricevere con \func{recvfrom} un valore di ritorno di 0 byte, senza che questo
 possa configurarsi come una chiusura della connessione\footnote{dato che la
   connessione non esiste, non ha senso parlare di chiusura della connessione,
   questo significa anche che con i socket UDP non è necessario usare
-  \func{close} o \func{shutdown} per terminare la cominicazione.} o come una
+  \func{close} o \func{shutdown} per terminare la comunicazione.} o come una
 cessazione delle comunicazioni.
 
 
@@ -304,7 +305,7 @@ sua volta un pacchetto UDP contenente la data.
   \label{fig:UDP_daytime_client}
 \end{figure}
 
-In \figref{fig:UDP_daytime_client} è riportato la sezione principale del
+In fig.~\ref{fig:UDP_daytime_client} è riportato la sezione principale del
 codice del nostro client, il sorgente completo si trova nel file
 \file{UDP\_daytime.c} distribuito con gli esempi allegati alla guida; al
 solito si è tralasciato di riportare in figura la sezione relativa alla
@@ -313,9 +314,9 @@ gestione delle opzioni a riga di comando (nel caso praticamente assenti).
 Il programma inizia (\texttt{\small 9--12}) con la creazione del socket, al
 solito uscendo dopo aver stampato un messaggio in caso errore. Si noti come in
 questo caso, rispetto all'analogo client basato su socket TCP di
-\figref{fig:TCP_daytime_client_code} si sia usato per il tipo di socket il
+fig.~\ref{fig:TCP_daytime_client_code} si sia usato per il tipo di socket il
 valore \const{SOCK\_DGRAM}, pur mantenendosi nella stessa famiglia data da
-\const{AF\_INET}. 
+\const{AF\_INET}.
 
 Il passo successivo (\texttt{\small 13--21}) è l'inizializzazione della
 struttura degli indirizzi; prima (\texttt{\small 14}) si cancella
@@ -324,17 +325,17 @@ la famiglia dell'indirizzo ed infine (\texttt{\small 16} la porta. Infine
 (\texttt{\small 18--21}) si ricava l'indirizzo del server da contattare dal
 parametro passato a riga di comando, convertendolo con \func{inet\_pton}. Si
 noti come questa sezione sia identica a quella del client TCP di
-\figref{fig:TCP_daytime_client_code}, in quanto la determinazione dell'uso di
-UDP al posto di TCP è stata effettuata quando si è creato il socket.
+fig.~\ref{fig:TCP_daytime_client_code}, in quanto la determinazione dell'uso
+di UDP al posto di TCP è stata effettuata quando si è creato il socket.
 
 Una volta completate le inizializzazioni inizia il corpo principale del
 programma, il primo passo è inviare, come richiesto dal protocollo, un
 pacchetto al server. Questo lo si fa (\texttt{\small 16}) inviando un
-pacchetto vuoto (si ricordi quanto detto in \secref{sec:UDP_sendto_recvfrom})
-con \func{sendto}, avendo cura di passare un valore nullo per il puntatore al
-buffer e la lunghezza del messaggio. In realtà il protocollo non richiede che
-il pacchetto sia vuoto, ma dato che il server comunque ne ignorerà il
-contenuto, è inutile inviare dei dati.
+pacchetto vuoto (si ricordi quanto detto in
+sez.~\ref{sec:UDP_sendto_recvfrom}) con \func{sendto}, avendo cura di passare
+un valore nullo per il puntatore al buffer e la lunghezza del messaggio. In
+realtà il protocollo non richiede che il pacchetto sia vuoto, ma dato che il
+server comunque ne ignorerà il contenuto, è inutile inviare dei dati.
 
 Verificato (\texttt{\small 24--27}) che non ci siano stati errori nell'invio
 si provvede (\texttt{\small 28}) ad invocare \func{recvfrom} per ricevere la
@@ -345,8 +346,8 @@ messaggio di risposta inviato dal server che 
 \var{buffer}, se (\texttt{\small 34}) pertanto il valore è positivo si
 provvederà (\texttt{\small 35}) a terminare la stringa contenuta nel buffer di
 lettura\footnote{si ricordi che, come illustrato in
-  \secref{sec:TCP_daytime_client}, il server invia in risposta una stringa
-  contenente la data, terminata dai due carratteri CR e LF, che pertanto prima
+  sez.~\ref{sec:TCP_daytime_client}, il server invia in risposta una stringa
+  contenente la data, terminata dai due caratteri CR e LF, che pertanto prima
   di essere stampata deve essere opportunamente terminata con un NUL.} e a
 stamparla (\texttt{\small 36}) sullo standard output, controllando anche in
 questo caso (\texttt{\small 36--38}) l'esito dell'operazione, ed uscendo con
@@ -380,7 +381,7 @@ errori anche se il server non 
 ascolto sull'indirizzo di destinazione. Questo comporta ad esempio che se si
 usa il nostro programma interrogando un server inesistente questo resterà
 perennemente bloccato nella chiamata a \func{recvfrom}, fin quando non lo
-interromperemo. Vedremo in \secref{sec:UDP_connect} come si può porre rimedio
+interromperemo. Vedremo in sez.~\ref{sec:UDP_connect} come si può porre rimedio
 a questa problematica.
 
 
@@ -404,7 +405,7 @@ stringa con la data corrente.
   \label{fig:UDP_daytime_server}
 \end{figure}
 
-In \figref{fig:UDP_daytime_server} è riportato la sezione principale del
+In fig.~\ref{fig:UDP_daytime_server} è riportato la sezione principale del
 codice del nostro client, il sorgente completo si trova nel file
 \file{UDP\_daytimed.c} distribuito con gli esempi allegati alla guida; anche
 in questo caso si è omessa la sezione relativa alla gestione delle opzioni a
@@ -413,8 +414,8 @@ video l'indirizzo associato ad ogni richiesta).
 
 Anche in questo caso la prima parte del server (\texttt{\small 9--23}) è
 sostanzialmente identica a quella dell'analogo server per TCP illustrato in
-\figref{fig:TCP_daytime_cunc_server_code}; si inizia (\texttt{\small 10}) con
-il creare il socket, uscendo con un messaggio in caso di errore
+fig.~\ref{fig:TCP_daytime_cunc_server_code}; si inizia (\texttt{\small 10})
+con il creare il socket, uscendo con un messaggio in caso di errore
 (\texttt{\small 10--13}), e di nuovo la sola differenza con il caso precedente
 è il diverso tipo di socket utilizzato. Dopo di che (\texttt{\small 14--18})
 si inizializza la struttura degli indirizzi che poi (\texttt{\small 20}) verrà
@@ -423,7 +424,7 @@ contenuto, si imposta (\texttt{\small 16}) la famiglia dell'indirizzo, la
 porta (\texttt{\small 17}) e l'indirizzo (\texttt{\small 18}) su cui si
 riceveranno i pacchetti.  Si noti come in quest'ultimo sia l'indirizzo
 generico \const{INADDR\_ANY}; questo significa (si ricordi quanto illustrato
-in \secref{sec:TCP_func_bind}) che il server accetterà pacchetti su uno
+in sez.~\ref{sec:TCP_func_bind}) che il server accetterà pacchetti su uno
 qualunque degli indirizzi presenti sulle interfacce di rete della macchina.
 
 Completata l'inizializzazione tutto quello che resta da fare è eseguire
@@ -449,14 +450,14 @@ inviati dai client. Lo scopo della funzione 
 volte che un pacchetto viene inviato al server, in modo da poter ricavare da
 esso l'indirizzo del client a cui inviare la risposta in \var{addr}. Per
 questo motivo in questo caso (al contrario di quanto fatto in
-\figref{fig:UDP_daytime_client}) si è avuto cura di passare gli argomenti
+fig.~\ref{fig:UDP_daytime_client}) si è avuto cura di passare gli argomenti
 \var{addr} e \var{len} alla funzione.  Dopo aver controllato (\texttt{\small
   27--30}) la presenza di eventuali errori (uscendo con un messaggio di errore
 qualora ve ne siano) si verifica (\texttt{\small 31}) se è stata attivata
 l'opzione \texttt{-v} (che imposta la variabile \var{verbose}) stampando nel
 caso (\texttt{\small 32--35}) l'indirizzo da cui si è appena ricevuto una
 richiesta (questa sezione è identica a quella del server TCP illustrato in
-\figref{fig:TCP_daytime_cunc_server_code}).
+fig.~\ref{fig:TCP_daytime_cunc_server_code}).
 
 Una volta ricevuta la richiesta resta solo da ottenere il tempo corrente
 (\texttt{\small 36}) e costruire (\texttt{\small 37}) la stringa di risposta,
@@ -498,54 +499,76 @@ 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}
 
-In \figref{fig:UDP_echo_client} è riportato un estratto del corpo principale
+In fig.~\ref{fig:UDP_echo_client} è riportato un estratto del corpo principale
 del nostro client elementare per il servizio \textit{echo} (al solito il
 codice completo è con i sorgenti allegati). Le uniche differenze con l'analogo
-client visto in \figref{fig:TCP_echo_client_1} sono che al solito si crea
+client visto in fig.~\ref{fig:TCP_echo_client_1} sono che al solito si crea
 (\texttt{\small 14}) un socket di tipo \const{SOCK\_DGRAM}, e che non è
 presente nessuna chiamata a \func{connect}. Per il resto il funzionamento del
 programma è identico, e tutto il lavoro viene effettuato attraverso la
-chiamata (\texttt{\small 28}), alla funzione \func{ClientEcho} che stavolta
+chiamata (\texttt{\small 28}) alla funzione \func{ClientEcho} che stavolta
 però prende un argomento in più, che è l'indirizzo del socket.
 
 \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
     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 \figref{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 parametro, che è l'indirizzo del server cui
+questa necessita anche di un terzo argomento, che è l'indirizzo del server cui
 inviare i pacchetti.
 
-Data l'assenza della connessione il meccanismo è molto più semplice da
-gestire. Al solito si esegue un ciclo infinito (\texttt{\small 6--30}) che
-parte dalla lettura (\texttt{\small 7}) di una stringa dallo standard input
-
-
-
-
+Data l'assenza di una connessione come nel caso di TCP il meccanismo è molto
+più semplice da gestire. Al solito si esegue un ciclo infinito (\texttt{\small
+  6--30}) che parte dalla lettura (\texttt{\small 7}) sul buffer di invio
+\var{sendbuff} di una stringa dallo standard input, se la stringa è vuota
+(\texttt{\small 7--9}), indicando che l'input è terminato, si ritorna
+immediatamente causando anche la susseguente terminazione del programma.
+
+Altrimenti si procede (\texttt{\small 10--11}) all'invio della stringa al
+destinatario invocando \func{sendto}, utilizzando, oltre alla stringa appena
+letta, gli argomenti passati nella chiamata a \func{ClientEcho}, ed in
+particolare l'indirizzo del server che si è posto in \var{serv\_addr}; qualora
+(\texttt{\small 12}) si riscontrasse un errore si provvederà al solito
+(\texttt{\small 13--14}) ad uscire con un messaggio di errore.
+
+Il passo immediatamente seguente (\texttt{\small 17}) l'invio è quello di
+leggere l'eventuale risposta del server con \func{recvfrom}; si noti come in
+questo caso si sia scelto di ignorare l'indirizzo dell'eventuale pacchetto di
+risposta, controllando (\texttt{\small 18--21}) soltanto la presenza di un
+errore (nel qual caso al solito si ritorna dopo la stampa di un adeguato
+messaggio). Si noti anche come, rispetto all'analoga funzione
+\func{ClientEcho} utilizzata nel client TCP illustrato in
+sez.~\ref{sec:TCP_echo_client} non si sia controllato il caso di un messaggio
+nullo, dato che, nel caso di socket UDP, questo non significa la terminazione
+della comunicazione.
+
+L'ultimo passo (\texttt{\small 17}) è quello di terminare opportunamente la
+stringa di risposta nel relativo buffer per poi provvedere alla sua stampa
+sullo standard output, eseguendo il solito controllo (ed eventuale uscita con
+adeguato messaggio informativo) in caso di errore.
 
 In genere fintanto che si esegue il nostro client in locale non sorgerà nessun
-problema, se però si prova ad eseguirlo attraverso un collegamento remoto (nel
-caso una VPN, attraverso una ADSL abbastanza congestionata) e in modalità non
-interattiva, la probabilità di perdere qualche pacchetto aumenta, ed infatti,
-eseguendo il comando come:
+problema, se però si proverà ad eseguirlo attraverso un collegamento remoto
+(nel caso dell'esempio seguente su una VPN, attraverso una ADSL abbastanza
+congestionata) e in modalità non interattiva, la probabilità di perdere
+qualche pacchetto aumenta, ed infatti, eseguendo il comando come:
 \begin{verbatim}
 [piccardi@gont sources]$ cat UDP_echo.c | ./echo 192.168.1.120
 /* UDP_echo.c
@@ -557,9 +580,10 @@ eseguendo il comando come:
  * Include needed headers
 
 \end{verbatim}%$
-si otterrà che dopo aver correttamente stampato alcune righe il programma si
-bloccherà completamente senza stampare più niente. Se al contempo si fosse
-tenuto sotto controllo il traffico UDP con \cmd{tcpdump} si sarebbe ottenuto:
+si otterrà che, dopo aver correttamente stampato alcune righe, il programma si
+blocca completamente senza stampare più niente. Se al contempo si fosse tenuto
+sotto controllo il traffico UDP diretto o proveniente dal servizio
+\textit{echo} con \cmd{tcpdump} si sarebbe ottenuto:
 \begin{verbatim}
 [root@gont gapil]# tcpdump  \( dst port 7 or src port 7 \)
 ...
@@ -570,28 +594,168 @@ tenuto sotto controllo il traffico UDP con \cmd{tcpdump} si sarebbe ottenuto:
 18:48:17.964917 192.168.1.120.echo > gont.earthsea.ea.32788: udp 26 (DF)
 18:48:17.965408 gont.earthsea.ea.32788 > 192.168.1.120.echo: udp 4 (DF)
 \end{verbatim}
-che come si vede termina con l'invio di un pacchetto UDP per il quale non si è
-ricevuto risposta.
+che come si vede il traffico fra client e server si interrompe dopo l'invio di
+un pacchetto UDP per il quale non si è ricevuto risposta.
+
+Il problema è che in tutti i casi in cui un pacchetto di risposta si perde, o
+una richiesta non arriva a destinazione, il nostro programma si bloccherà
+nell'esecuzione di \func{recvfrom}. Lo stesso avviene anche se il server non è
+in ascolto, in questo caso però, almeno dal punto di vista dello scambio di
+pacchetti, il risultato è diverso, se si lancia al solito il programma e si
+prova a scrivere qualcosa si avrà ugualmente un blocco su \func{recvfrom} ma
+se si osserva il traffico con \cmd{tcpdump} si vedrà qualcosa del tipo:
+\begin{verbatim}
+[root@gont gapil]# tcpdump  \( dst 192.168.0.2 and src 192.168.1.120 \) \
+   or \( src 192.168.0.2 and dst 192.168.1.120 \)
+tcpdump: listening on eth0
+00:43:27.606944 gont.earthsea.ea.32789 > 192.168.1.120.echo: udp 6 (DF)
+00:43:27.990560 192.168.1.120 > gont.earthsea.ea: icmp: 192.168.1.120 udp port 
+echo unreachable [tos 0xc0]
+\end{verbatim}
+cioè in questo caso si avrà in risposta un pacchetto ICMP di destinazione
+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 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,\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 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.
 
 
 
 \subsection{L'uso della funzione \func{connect} con i socket UDP}
 \label{sec:UDP_connect}
 
-Come illustrato in \secref{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. 
+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. 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 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.
+
+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
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/UDP_echo.c}
+  \end{minipage}
+  \normalsize
+  \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
+socket \textit{netlink} che definiscono una interfaccia di comunicazione con
+il kernel.