Finito server daytime su UDP
[gapil.git] / othersock.tex
index 1f1023553f71a92485f197a8838a2df6272aed9f..bbd2e7660399fab4d27c2368b117685a2bd15a34 100644 (file)
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
-\chapter{Gli altri socket più comuni}
+\chapter{Gli altri tipi di socket}
 \label{cha:other_socket}
 
 Dopo aver trattato in \capref{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, 
+capitolo gli altri tipi di socket, a partire dai socket UDP, e i socket deiit
+\textit{Unix domain} già incontrati in \secref{sec:ipc_socketpair}.
 
 
 \section{I socket UDP}
 \label{sec:UDP_socket}
 
-Dopo i socket TCP i socket più utilizzati sono i socket UDP. 
+Dopo i socket TCP i socket più utilizzati nella programmazione di rete sono i
+socket UDP: protocolli diffusi come NFS o il DNS usano principalmente questo
+tipo di socket. Tratteremo in questa sezione le loro caratteristiche
+principali e le modalità per il loro utilizzo.
+
+
+\subsection{Le caratteristiche di un socket UDP}
+\label{sec:UDP_characteristics}
+
+Come illustrato in \secref{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
+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ù
+veloce ed immediata.
+
+Questo significa che a differenza dei socket TCP i socket UDP non supportano
+una comunicazione di tipo \textit{stream} in cui si ha a disposizione un
+flusso continuo di dati che può essere letto un po' alla volta, ma piuttosto
+una comunicazione di tipo \textit{datagram}, in cui i dati arrivano in singoli
+blocchi che devono essere letti integralmente.
+
+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})
+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
+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}.
+
+\begin{figure}[htb]
+  \centering
+  \includegraphics[width=10cm]{img/udp_connection}  
+  \caption{Lo schema di interscambio dei pacchetti per una comunicazione via
+     UDP.}
+  \label{fig:UDP_packet-exchange}
+\end{figure}
+
+Come illustrato in \figref{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}. 
+
+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
+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}.
+
+Anche se UDP è completamente diverso rispetto a TCP resta identica la
+possibilità di gestire più canali di comunicazione fra due macchine
+utilizzando le porte. In questo caso il server dovrà usare comunque la
+funzione \func{bind} per scegliere la porta su cui ricevere i dati, e come nel
+caso dei socket TCP si potrà usare il comando \cmd{netstat} per
+verificare quali socket sono in ascolto:
+\begin{verbatim}
+[piccardi@gont gapil]# netstat -anu
+Active Internet connections (servers and established)
+Proto Recv-Q Send-Q Local Address           Foreign Address         State
+udp        0      0 0.0.0.0:32768           0.0.0.0:*
+udp        0      0 192.168.1.2:53          0.0.0.0:*
+udp        0      0 127.0.0.1:53            0.0.0.0:*
+udp        0      0 0.0.0.0:67              0.0.0.0:*
+\end{verbatim}
+in questo caso abbiamo attivi il DNS (sulla porta 53, e sulla 32768 per la
+connessione di controllo del server \cmd{named}) ed un server DHCP (sulla
+porta 67).
+
+Si noti però come in questo caso la colonna che indica lo stato sia vuota. I
+socket UDP infatti non hanno uno stato. Inoltre anche in presenza di traffico
+non si avranno indicazioni delle connessioni attive, proprio perché questo
+concetto non esiste per i socket UDP, il kernel si limita infatti a ricevere i
+pacchetti ed inviarli al processo in ascolto sulla porta cui essi sono
+destinati, oppure a scartarli inviando un messaggio \textit{ICMP port
+  unreachable} qualora non vi sia nessun processo in ascolto.
+
+
+\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
+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
+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
+  \textit{Single Unix Specification}, l'argomento \param{flags} era di tipo
+  \type{int} nei vari BSD4.*, mentre nelle \acr{libc4} e \acr{libc5} veniva
+  usato un \type{unsigned int}; l'argomento \param{len} era \type{int} nei
+  vari BSD4.* e nelle \acr{libc4}, ma \type{size\_t} nelle \acr{libc5}; infine
+  l'argomento \param{tolen} era \type{int} nei vari BSD4.* nelle \acr{libc4} e
+  nelle \acr{libc5}.} è:
+\begin{functions}
+  \headdecl{sys/types.h}
+  \headdecl{sys/socket.h}
+  
+  \funcdecl{ssize\_t sendto(int sockfd, const void *buf, size\_t len, int
+    flags, const struct sockaddr *to, socklen\_t tolen)}
+  
+  Trasmette un messaggio ad un altro socket.
+  
+  \bodydesc{La funzione restituisce il numero di caratteri inviati in caso di
+    successo e -1 per un errore; nel qual caso \var{errno} viene impostata al
+    rispettivo codice di errore:
+  \begin{errlist}
+  \item[\errcode{EAGAIN}] il socket è in modalità non bloccante, ma
+    l'operazione richede che la funzione si blocchi.
+  \item[\errcode{ECONNRESET}] l'altro capo della comunicazione ha resettato la
+    conessione.
+  \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
+    destinatario.
+  \item[\errcode{EMSGSIZE}] il tipo di socket richiede l'invio dei dati in un
+    blocco unico, ma la dimensione del messaggio lo rende impossibile.
+  \item[\errcode{ENOBUFS}] la coda di uscita dell'interfaccia è già piena (di
+    norma Linux non usa questo messaggio ma scarta silenziosamente i
+    pacchetti).
+  \item[\errcode{ENOTCONN}] il socket non è connesso e non si è specificata
+    una destinazione.
+  \item[\errcode{EOPNOTSUPP}] il valore di \param{flag} non è appropriato per
+    il tipo di socket usato.
+  \item[\errcode{EPIPE}] il capo locale della connessione è stato chiuso, si
+    riceverà anche un segnale di \const{SIGPIPE}, a meno di non aver impostato
+    \const{MSG\_NOSIGNAL} in \param{flags}.
+  \end{errlist}
+  ed anche \errval{EFAULT}, \errval{EBADF}, \errval{EINVAL}, \errval{EINTR},
+  \errval{ENOMEM}, \errval{ENOTSOCK} più gli eventuali altri errori relativi
+  ai protocolli utilizzati.}
+\end{functions}
+
+I primi tre argomenti sono identici a quelli della funzione \func{write} e
+specificano il socket \param{sockfd} a cui si fa riferimento, il buffer
+\param{buf} che contiene i dati da inviare e la relativa lunghezza
+\param{len}.  Come per \func{write} la funzione ritorna il numero di byte
+inviati; nel caso di UDP però questo deve sempre corrispondere alla dimensione
+totale specificata da \param{len} in quanto i dati vengono sempre inviati in
+forma di pacchetto e non possono essere spezzati in invii successivi.  Qualora
+non ci sia spazio nel buffer di uscita la funzione si blocca (a meno di non
+avere aperto il socket in modalità non bloccante), se invece non è possibile
+inviare il messaggio all'interno di un unico pacchetto (ad esempio perché
+eccede le dimensioni massime del protocollo sottostante utilizzato) essa
+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
+vanno specificati stessa forma in cui li si sarebbero usati con
+\func{connect}. Nel nostro caso \param{to} devrà 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
+indirizzi).
+
+Se il socket è di un tipo che prevede le connessioni (ad esempio un 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
+qualora si sia specificato un indirizzo è possibile ricevere un errore di
+\errcode{EISCONN}.
+
+Finora abbiamo tralasciato l'argomento \param{flags}; questo è un intero usato
+come maschera binaria che permette di impostare una serie di modalità di
+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.
+
+La seconda funzione utilizzata nella comunicazione fra socket UDP è
+\funcd{recvfrom}, che serve a ricevere i dati inviati da un altro socket; il
+suo prototipo\footnote{il prototipo è quello delle \acr{glibc} che seguono le
+  \textit{Single Unix Specification}, i vari BSD4.*, le \acr{libc4} e le
+  \acr{libc5} usano un \type{int} come valore di ritorno; per gli argomenti
+  \param{flags} e \param{len} vale quanto detto a proposito di \func{sendto};
+  infine l'argomento \param{fromlen} è \type{int} per i vari BSD4.*, le
+  \acr{libc4} e le \acr{libc5}.} è:
+\begin{functions}
+  \headdecl{sys/types.h}
+  \headdecl{sys/socket.h}
+  
+  \funcdecl{ssize\_t recvfrom(int sockfd, const void *buf, size\_t len, int
+    flags, const struct sockaddr *from, socklen\_t *fromlen)}
+  
+  Riceve un messaggio ad un socket.
+  
+  \bodydesc{La funzione restituisce il numero di byte ricevuti in caso di
+    successo e -1 in caso di errore; nel qual caso \var{errno} assumerà il
+    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
+    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).
+  \item[\errcode{ENOTCONN}] il socket è di tipo connesso, ma non si è eseguita
+    la connessione.
+  \end{errlist}
+  ed anche \errval{EFAULT}, \errval{EBADF}, \errval{EINVAL}, \errval{EINTR},
+  \errval{ENOMEM}, \errval{ENOTSOCK} più gli eventuali altri errori relativi
+  ai protocolli utilizzati.}
+\end{functions}
+
+Come per \func{sendto} i primi tre argomenti sono identici agli analoghi di
+\func{read}: dal socket vengono letti \param{len} byte che vengono salvati nel
+buffer \param{buf}. A seconda del tipo di socket (se di tipo \textit{datagram}
+o di tipo \textit{stream}) i byte in eccesso che non sono stati letti possono
+rispettivamente andare persi o restare disponibili per una lettura successiva.
+Se non sono disponibili dati la funzione si blocca, a meno di non aver aperto
+il socket in modalità non bloccante, nel qual caso si avrà il solito errore di
+\errcode{EAGAIN}.  Qualora \param{len} ecceda la dimensione del pacchetto la
+funzione legge comunque i dati disponibili, ed il suo valore di ritorno è
+comunque il numero di byte letti.
+
+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}.
+
+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
+questo caso è perfettamente legale inviare con \func{sendto} un pacchetto
+vuoto (che nel caso conterrà solo le intestazioni di IP e di UDP),
+specificando un valore nullo per \param{len}. Allo stesso modo è possibile
+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
+cessazione delle comunicazioni.
+
+
+
+\subsection{Un client UDP elementare}
+\label{sec:UDP_daytime_client}
+
+Vediamo allora come implementare un primo client elementare con dei socket
+UDP.  Ricalcando quanto fatto nel caso dei socket TCP prenderemo come primo
+esempio l'uso del servizio \textit{daytime}, utilizzando questa volta UDP. Il
+servizio è definito nell'\href{http://www.ietf.org/rfc/rfc0862.txt}{RFC~867},
+che nel caso di uso di UDP prescrive che il client debba inviare un pacchetto
+UDP al server (di contenuto non specificato), il quale risponderà a inviando a
+sua volta un pacchetto UDP contenente la data.
+
+\begin{figure}[!htb] 
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/UDP_daytime.c}
+  \end{minipage} 
+  \normalsize
+  \caption{Sezione principale del client per il servizio \textit{daytime} su
+    UDP.}
+  \label{fig:UDP_daytime_client}
+\end{figure}
+
+In \figref{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
+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
+valore \const{SOCK\_DGRAM}, pur mantenendosi nella stessa famiglia data da
+\const{AF\_INET}. 
+
+Il passo successivo (\texttt{\small 13--21}) è l'inizializzazione della
+struttura degli indirizzi; prima (\texttt{\small 14}) si cancella
+completamente la stessa con \func{memset}, (\texttt{\small 15}) poi si imposta
+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.
+
+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.
+
+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
+risposta del server. Si controlla poi (\texttt{\small 29--32}) che non vi
+siano stati errori in ricezione (uscendo con un messaggio in caso contrario);
+se è tutto a posto la variabile \var{nread} conterrà la dimensione del
+messaggio di risposta inviato dal server che è stato memorizzato su
+\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
+  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
+un messaggio in caso di errore.
+
+Se pertanto si è avuto cura di attivare il server del servizio
+\textit{daytime}\footnote{di norma questo è un servizio standard fornito dal
+  \textsl{superdemone} \cmd{inetd}, per cui basta abilitarlo nel file di
+  configurazione di quest'ultimo, avendo cura di predisporre il servizio su
+  UDP.} potremo verificare il funzionamento del nostro client interrogando
+quest'ultimo con:
+\begin{verbatim}
+[piccardi@gont sources]$ ./daytime 127.0.0.1
+Sat Mar 20 23:17:13 2004
+\end{verbatim}%$
+ed osservando il traffico con uno sniffer potremo effettivamente vedere lo
+scambio dei due pacchetti, quello vuoto di richiesta, e la risposta del
+server:
+\begin{verbatim}
+[root@gont gapil]# tcpdump -i lo
+tcpdump: listening on lo
+23:41:21.645579 localhost.32780 > localhost.daytime: udp 0 (DF)
+23:41:21.645710 localhost.daytime > localhost.32780: udp 26 (DF)
+\end{verbatim}
+
+Una differenza fondamentale del nostro client è che in questo caso, non
+disponendo di una connessione, è per lui impossibile riconoscere errori di
+invio relativi alla rete. La funzione \func{sendto} infatti riporta solo
+errori locali, i dati vengono comunque scritti e la funzione ritorna senza
+errori anche se il server non è raggiungibile o non esiste un server in
+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
+a questa problematica.
+
+
+\subsection{Un server UDP elementare}
+\label{sec:UDP_daytime_server}
+
+Nella sezione precedente abbiamo visto come scrivere un client elementare per
+servizio \textit{daytime}, vediamo in questa come deve essere scritto un
+server.  Si ricordi che il compito di quest'ultimo è quello di ricevere un
+pacchetto di richiesta ed inviare in risposta un pacchetto contenente una
+stringa con la data corrente. 
+
+\begin{figure}[!htb] 
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/UDP_daytimed.c}
+  \end{minipage} 
+  \normalsize
+  \caption{Sezione principale del server per il servizio \textit{daytime} su
+    UDP.}
+  \label{fig:UDP_daytime_server}
+\end{figure}
+
+In \figref{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
+riga di comando (la sola presente è \texttt{-v} che permette di stampare a
+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
+(\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à
+usata da \func{bind}; si cancella (\texttt{\small 15}) preventivamente il
+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
+qualunque degli indirizzi presenti sulle interfacce di rete della macchina.
+
+Completata l'inizializzazione tutto quello che resta da fare è eseguire
+(\texttt{\small 20--23}) la chiamata a \func{bind}, controllando la presenza
+di eventuali errori, ed uscendo con un avviso qualora questo fosse il caso.
+Nel caso di socket UDP questo è tutto quello che serve per consentire al
+server di ricevere i pacchetti a lui indirizzati, e non è più necessario
+chiamare successivamente \func{listen}. In questo caso infatti non esiste il
+concetto di connessione, e quindi non deve essere predisposta una coda delle
+connessioni entranti. Nel caso di UDP i pacchetti arrivano al kernel con un
+certo indirizzo ed una certa porta di destinazione, il kernel controlla se
+corrispondono ad un socket che è stato \textsl{legato} ad essi con
+\func{bind}, qualora questo sia il caso scriverà il contenuto all'interno del
+socket, così che il programma possa leggerlo, altrimenti risponderà alla
+macchina che ha inviato il pacchetto con un messaggio ICMP di tipo
+\textit{port unreachable}.
+
+Una volta completata la fase di inizializzazione inizia il corpo principale
+(\texttt{\small 24--44}) del server, mantenuto all'interno di un ciclo
+infinito in cui si trattano le richieste. Il ciclo inizia (\texttt{\small 26})
+con una chiamata a \func{recvfrom}, che si bloccherà in attesa di pacchetti
+inviati dai client. Lo scopo della funzione è quello di ritornare tutte le
+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 opportuni
+argomenti 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}).
+
+Una volta ricevuta la richiesta resta solo da ottenere il tempo corrente
+(\texttt{\small 36}) e costruire (\texttt{\small 37}) la stringa di risposta,
+che poi verrà inviata (\texttt{\small 38}) al client usando \func{sendto},
+avendo al solito cura di controllare (\texttt{\small 40--42}) lo stato di
+uscita della funzione e trattando opportunamente la condizione di errore.
+
+Si noti come per le peculiarità del protocollo si sia utilizzato un server
+iterativo, che processa le richieste una alla volta via via che gli arrivano.
+Questa è una caratteristica comune dei server UDP, conseguenza diretta del
+fatto che non esiste il concetto di connessione, per cui non c'è la necessità
+di trattare separatamente le singole connessioni. Questo significa anche che è
+il kernel a gestire la possibilità di richieste multiple in contemporanea;
+quello che succede è semplicemente che il kernel accumula in un buffer in
+ingresso i pacchetti che arrivano e li restituisce al processo uno alla volta
+per ciascuna chiamata di \func{recvfrom}; è poi compito del server distribuire
+le risposte sulla base dell'indirizzo da cui provengono le richieste.
+
+
+
+
+\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.
+
 
 
 \section{I socket \textit{Unix domain}}
-\label{sec:UDP_socket}
+\label{sec:unix_socket}
 
-Benché i socket Unix domain non siano strattamente attinenti alla rete, in
+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.
@@ -33,6 +498,7 @@ interfaccia 
 
 
 
+
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"