%% 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 nella programmazione di rete sono i
-socket UDP; protocolli diffusi come NFS o il DNS usano principalmente questo
+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.
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é non esiste
-niente di simile per i socket UDP, il kernel si limita infatti a ricevere i
+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.
\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
+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
Per questo motivo nel caso di UDP diventa essenziale utilizzare queste due
funzioni, che sono comunque usabili in generale per la trasmissione di dati
-attraverso qualunque tipo di socket, dato che esse hanno la caratteristica di
-provvedere tre argomenti aggiuntivi che consentono di specificare destinazione
-o origine dei dati trasmessi. La prima delle due 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}.} è:
+attraverso qualunque tipo di socket. Esse hanno la caratteristica di prevedere
+tre argomenti aggiuntivi attraveso i quali è possibile specificare la
+destinazione o l'origine dei dati trasmessi. 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}
I due argomenti \param{to} e \param{tolen} servono a specificare la
destinazione del messaggio da inviare, e prendono l'indirizzo di quest'ultima,
nella stessa forma in cui lo si specificherebbe per \func{connect}: \param{to}
-deve cioè contere l'indirizzo IP e la porta di destinazione cui si vogliono
-inviare i dati e \param{tolen} la relativa dimensione.
+deve cioè contenere l'indirizzo IP e la porta di destinazione cui si vogliono
+inviare i dati e \param{tolen} la relativa dimensione.
Se il socket è di un tipo che prevede le connessioni, questo deve essere già
connesso prima di eseguire la funzione (altrimenti si avrà un errore 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 \textit{stream}) inoltre 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}.
-
+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 quest'ultimo
+e la sua lunghezza saranno memorizzati (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}.
+
+Un'altra differenza fondamentale 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), scrivendo 0 byte. Allo
+stesso è 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, pertanto con i socket UDP non è necessario
+ usare \func{close} per terminare la cominicazione.} o come una cessazione
+delle comunicazioni.
+
+
+\subsection{Un client elementare}
+\label{sec:UDP_simple_server}
+
+Vediamo allora come implementare un primo server elementare su UDP; ricalcando
+quanto fatto nel caso dei socket TCP prenderemo come primo esempio l'uso del
+servizio \textit{time}, utilizzanto questa volta UDP.