Riorganizzate varie parti, rimetto in linea la nuova versione
[gapil.git] / socket.tex
index e20c388..e0057fd 100644 (file)
@@ -1,14 +1,35 @@
 \chapter{Introduzione ai socket}
 \label{cha:socket_intro}
 
-Il \textit{socket} (traducibile liberamente come \textsl{manicotto}) è uno dei
-principali meccanismi di comunicazione fra programmi utilizzato in ambito unix
-(e non solo). Il socket costituisce in sostanza un canale di comunicazione fra
-due processi su cui si possono leggere e scrivere dati analogo a quello di una
-pipe ma a differenza di questa e degli altri meccanismi esaminati nel capitolo
-\capref{cha:IPC} i socket non sono limitati alla comunicazione fra processi
-che girano sulla stessa macchina ma possono effettuare la comunicazione anche
-attraverso la rete.
+In questo capitolo inizieremo a spiegare le caratteristiche principali della
+principale interfaccia per la programmazione di rete, quella dei
+\textit{socket}, che pur essendo nata in unix è usata ormai da tutti i sistemi
+operativi.
+
+Dopo una breve panoramica sulle caratteristiche di questa interfaccia vedremo
+come creare un socket e come collegarlo allo specifico protocollo di rete che
+utilizzerà per la comunicazione. Per evitare una introduzione puramente teorica
+concluderemo il capitolo con un primo esempio di applicazione.
+
+\section{Una panoramica}
+\label{sec:sock_overview}
+
+Iniziamo con una descrizione essenziale di cosa sono i \textit{socket} e di
+quali sono i concetti fondamentali da tenere presente quando si ha a che fare
+con essi.
+
+\subsection{I \textit{socket}}
+\label{sec:sock_socket_def}
+
+Il \textit{socket}\footnote{una traduzione letterale potrebbe essere
+  \textsl{manicotto}, ma essendo universalmente noti come socket utilizzeremo
+  sempre la parola inglese} è uno dei principali meccanismi di comunicazione
+fra programmi utilizzato in ambito unix. Il socket costituisce in sostanza un
+canale di comunicazione fra due processi su cui si possono leggere e scrivere
+dati analogo a quello di una pipe ma a differenza di questa e degli altri
+meccanismi esaminati nel capitolo \capref{cha:IPC} i socket non sono limitati
+alla comunicazione fra processi che girano sulla stessa macchina ma possono
+effettuare la comunicazione anche attraverso la rete.
 
 Quella dei socket costituisce infatti la principale API (\textit{Application
   Program Interface}) usata nella programmazione di rete.  La loro origine
@@ -25,7 +46,7 @@ solo con la suite dei protocolli TCP/IP, che sar
 tratteremo in maniera più estesa.
 
 
-\section{Concetti base}
+\subsection{Concetti base}
 \label{sec:sock_gen}
 
 Per capire il funzionamento dei socket occorre avere presente il funzionamento
@@ -64,13 +85,21 @@ la comunicazione, ad esempio se 
 gestire la perdita o il rimescolamento dei dati.
 
 
-\section{La funzione \texttt{socket}}
+\section{La creazione di un \textit{socket}}
+\label{sec:sock_creation}
+
+Come accennato l'interfaccia dei socket è estremamente flessibile e permette
+di interagire con protocolli di comunicazione anche molto diversi fra di loro;
+in questa sezione vedremo come è possibile creare un socket e come specificare
+il tipo di comunicazione che esso deve utilizzare.
+
+\subsection{La funzione \texttt{socket}}
 \label{sec:sock_socket}
 
 La creazione di un socket avviene attraverso l'uso della funzione
 \texttt{socket} questa restituisce un \textit{socket descriptor} (un valore
-intero non negativo) che come gli analoghi file descriptor di files e alle
-pipes serve come riferimento al socket; in sostanza è l'indice nella tabella
+intero non negativo) che come gli analoghi file descriptor di file e alle
+pipe serve come riferimento al socket; in sostanza è l'indice nella tabella
 dei file che contiene i puntatori alle opportune strutture usate dal kernel ed
 allocate per ogni processo, (la stessa usata per i files e le pipes [NdA
 verificare!]).
@@ -137,7 +166,9 @@ protocolli disponibili sono riportate in \ntab.
   \footnotesize
   \centering
   \begin{tabular}[c]{lll}
-       Nome               & Utilizzo                       & Man page   \\
+       \hline
+       \textsl{Nome}      & \textsl{Utilizzo}             &\textsl{Man page} \\
+       \hline
        \hline
        PF\_UNIX,PF\_LOCAL & Local communication            & unix(7)    \\
        PF\_INET           & IPv4 Internet protocols        & ip(7)      \\
@@ -149,15 +180,16 @@ protocolli disponibili sono riportate in \ntab.
        PF\_ATMPVC         & Access to raw ATM PVCs         &            \\
        PF\_APPLETALK      & Appletalk                      & ddp(7)     \\
        PF\_PACKET         & Low level packet interface     & packet(7)  \\    
+       \hline
   \end{tabular}
   \caption{Famiglie di protocolli definiti in Linux}
   \label{tab:net_pf_names}
 \end{table}
 
 Non tutte le famiglie di protocolli sono accessibili dall'utente generico, ad
-esempio in generale tutti i socket di tipo \texttt{SOCK\_RAW} possono essere
+esempio in generale tutti i socket di tipo \macro{SOCK\_RAW} possono essere
 creati solo da processi che hanno i privilegi di root (cioè effective uid
-uguale a zero) o la capability \texttt{CAP\_NET\_RAW}.
+uguale a zero) o la capability \macro{CAP\_NET\_RAW}.
 
 
 \subsection{Il tipo, o stile}
@@ -168,26 +200,26 @@ comunicazione, questo infatti viene a dipendere dal protocollo che si andr
 utilizzare fra quelli disponibili nella famiglia scelta. Le API permettono di
 scegliere lo stile di comunicazione indicando il tipo di socket; Linux e le
 glibc mettono a disposizione i seguenti tipi di socket (che il manuale della
-glibc chiama \textit{styles}) definiti come \texttt{int} in \texttt{socket.h}:
+glibc chiama \textit{styles}) definiti come \type{int} in \file{socket.h}:
 
 \begin{list}{}{}
-\item \texttt{SOCK\_STREAM} Provvede un canale di trasmissione dati
+\item \macro{SOCK\_STREAM} Provvede un canale di trasmissione dati
   bidirezionale, sequenziale e affidabile. Opera su una connessione con un
   altro socket. I dati vengono ricevuti e trasmessi come un flusso continuo di
   byte (da cui il nome \textit{stream}). 
-\item \texttt{SOCK\_DGRAM} Viene usato per mandare pacchetti di lunghezza
+\item \macro{SOCK\_DGRAM} Viene usato per mandare pacchetti di lunghezza
   massima fissata (\textit{datagram}) indirizzati singolarmente, senza
   connessione e in maniera non affidabile. È l'opposto del precedente. 
-\item \texttt{SOCK\_SEQPACKET} Provvede un canale di trasmissione di dati
+\item \macro{SOCK\_SEQPACKET} Provvede un canale di trasmissione di dati
   bidirezionale, sequenziale e affidabile. Opera su una connessione con un
   altro socket. I dati possono solo essere trasmessi e letti per pacchetti (di
   dimensione massima fissata).
-\item \texttt{SOCK\_RAW} Provvede l'accesso a basso livello ai protocolli di
+\item \macro{SOCK\_RAW} Provvede l'accesso a basso livello ai protocolli di
   rete e alle varie interfacce. I normali programmi di comunicazione non
   devono usarlo.
-\item \texttt{SOCK\_RDM} Provvede un canale di trasmissione di pacchetti
+\item \macro{SOCK\_RDM} Provvede un canale di trasmissione di pacchetti
   affidabile ma in cui non è garantito l'ordine di arrivo dei pacchetti.
-\item \texttt{SOCK\_PACKET} Obsoleto, non deve essere usato.
+\item \macro{SOCK\_PACKET} Obsoleto, non deve essere usato.
 \end{list}
 
 Si tenga presente che non tutte le combinazioni di famiglia di protocolli e
@@ -199,34 +231,35 @@ tabella che mostra le combinazioni valide 
   \footnotesize
   \centering
   \begin{tabular}{l|c|c|c|c|c|}
-   \multicolumn{1}{c}{} &\multicolumn{1}{c}{\texttt{SOCK\_STREAM}}& 
-     \multicolumn{1}{c}{\texttt{SOCK\_DGRAM}} & 
-     \multicolumn{1}{c}{\texttt{SOCK\_RAW}} & 
-     \multicolumn{1}{c}{\texttt{SOCK\_PACKET}}& 
-     \multicolumn{1}{c}{\texttt{SOCK\_SEQPACKET}} \\
+   \multicolumn{1}{c}{} &\multicolumn{1}{c}{\macro{SOCK\_STREAM}}& 
+     \multicolumn{1}{c}{\macro{SOCK\_DGRAM}} & 
+     \multicolumn{1}{c}{\macro{SOCK\_RAW}} & 
+     \multicolumn{1}{c}{\macro{SOCK\_PACKET}}& 
+     \multicolumn{1}{c}{\macro{SOCK\_SEQPACKET}} \\
      \cline{2-6}
-    \texttt{PF\_UNIX}      &  si & si  &      &     &     \\
+    \macro{PF\_UNIX}      &  si & si  &      &     &     \\
      \cline{2-6}
-    \texttt{PF\_INET}      & TCP & UDP & IPv4 &     &     \\
+    \macro{PF\_INET}      & TCP & UDP & IPv4 &     &     \\
      \cline{2-6}
-    \texttt{PF\_INET6}     & TCP & UDP & IPv6 &     &     \\
+    \macro{PF\_INET6}     & TCP & UDP & IPv6 &     &     \\
      \cline{2-6}
-    \texttt{PF\_IPX}       &     &     &      &     &     \\
+    \macro{PF\_IPX}       &     &     &      &     &     \\
      \cline{2-6}
-    \texttt{PF\_NETLINK}   &     &  si &  si  &     &     \\
+    \macro{PF\_NETLINK}   &     &  si &  si  &     &     \\
      \cline{2-6}
-    \texttt{PF\_X25}       &     &     &      &     &  si \\
+    \macro{PF\_X25}       &     &     &      &     &  si \\
      \cline{2-6}
-    \texttt{PF\_AX25}      &     &     &      &     &     \\
+    \macro{PF\_AX25}      &     &     &      &     &     \\
      \cline{2-6}
-    \texttt{PF\_ATMPVC}    &     &     &      &     &     \\
+    \macro{PF\_ATMPVC}    &     &     &      &     &     \\
      \cline{2-6}
-    \texttt{PF\_APPLETALK} &     & si  &  si  &     &     \\
+    \macro{PF\_APPLETALK} &     & si  &  si  &     &     \\
      \cline{2-6}
-    \texttt{PF\_PACKET}    &     & si  & si   &     &     \\    
+    \macro{PF\_PACKET}    &     & si  & si   &     &     \\    
      \cline{2-6}
   \end{tabular}
-  \caption{Combinazioni valide di dominio e tipo di protocollo per la funzione \texttt{socket}.}
+  \caption{Combinazioni valide di dominio e tipo di protocollo per la 
+    funzione \func{socket}.}
   \label{tab:sock_sock_valid_combinations}
 \end{table}
 
@@ -234,6 +267,8 @@ Dove per ogni combinazione valida si 
 parola \textsl{si} qualora non il protocollo non abbia un nome definito,
 mentre si sono lasciate vuote le caselle per le combinazioni non supportate.
 
+
+
 \section{Le strutture degli indirizzi dei socket}
 \label{sec:sock_sockaddr}
 
@@ -253,6 +288,7 @@ tutte queste strutture iniziano per \texttt{sockaddr\_}, quelli propri di
 ciascuna famiglia vengono identificati dal suffisso finale, aggiunto al nome
 precedente.
 
+
 \subsection{La struttura generica}
 \label{sec:sock_sa_gen}
 
@@ -261,12 +297,12 @@ attraverso puntatori (cio
 maneggiare puntatori a strutture relative a tutti gli indirizzi possibili
 nelle varie famiglie di protocolli; questo pone il problema di come passare
 questi puntatori, il C ANSI risolve questo problema coi i puntatori generici
-(i \texttt{void *}), ma l'interfaccia dei socket è antecendente alla
+(i \type{void *}), ma l'interfaccia dei socket è antecendente alla
 definizione dello standard ANSI, e per questo nel 1982 fu scelto di definire
-una struttura generica \texttt{sockaddr} per gli indirizzi dei socket mostrata
+una struttura generica \type{sockaddr} per gli indirizzi dei socket mostrata
 in \nfig:
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
   \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 struct sockaddr {
@@ -274,7 +310,7 @@ struct sockaddr {
     char         sa_data[14];   /* address (protocol-specific) */
 };
   \end{lstlisting}
-  \caption{La struttura generica degli indirizzi dei socket \texttt{sockaddr}}
+  \caption{La struttura generica degli indirizzi dei socket \type{sockaddr}}
   \label{fig:sock_sa_gen_struct}
 \end{figure}
 
@@ -286,9 +322,9 @@ occorrer
 I tipi di dati che compongono la struttura sono stabiliti dallo standard
 POSIX.1g, riassunti in \ntab\ con i rispettivi file di include in cui sono
 definiti; la struttura è invece definita nell'include file
-\texttt{sys/socket.h}
+\file{sys/socket.h}
 
-\begin{table}[!htbp]
+\begin{table}[!htb]
   \centering
   \begin{tabular}{|l|l|l|}
     \hline
@@ -321,8 +357,8 @@ definiti; la struttura 
 In alcuni sistemi la struttura è leggermente diversa e prevede un primo membro
 aggiuntivo \texttt{uint8\_t sin\_len} (come riportato da R. Stevens nei suoi
 libri). Questo campo non verrebbe usato direttamente dal programmatore e non è
-richiesto dallo standard POSIX.1g, in Linux pertanto non sussiste. Il campo
-\texttt{sa\_family\_t} era storicamente un \texttt{unsigned short}.
+richiesto dallo standard POSIX.1g, in Linux pertanto non esiste. Il campo
+\type{sa\_family\_t} era storicamente un \type{unsigned short}.
 
 Dal punto di vista del programmatore l'unico uso di questa struttura è quello
 di fare da riferimento per il casting, per il kernel le cose sono un po'
@@ -336,14 +372,13 @@ l'uso di questa struttura.
 \subsection{La struttura degli indirizzi IPv4}
 \label{sec:sock_sa_ipv4}
 
-I socket di tipo \texttt{PF\_INET} vengono usati per la comunicazione
+I socket di tipo \macro{PF\_INET} vengono usati per la comunicazione
 attraverso internet; la struttura per gli indirizzi per un socket internet
-(IPv4) è definita come \texttt{sockaddr\_in} nell'header file
+(IPv4) è definita come \type{sockaddr\_in} nell'header file
 \texttt{netinet/in.h} e secondo le man page ha la forma mostrata in \nfig,
 conforme allo standard POSIX.1g.
 
-
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
   \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 struct sockaddr_in {
@@ -373,12 +408,12 @@ specifica il numero di porta (vedi \secref{sec:TCPel_port_num}; i numeri di
 porta sotto il 1024 sono chiamati \textsl{riservati} in quanto utilizzati da
 servizi standard. Soltanto processi con i privilegi di root (effective uid
 uguale a zero) o con la capability \texttt{CAP\_NET\_BIND\_SERVICE} possono
-usare la funzione \texttt{bind} su queste porte.
+usare la funzione \func{bind} su queste porte.
 
 Il membro \texttt{sin\_addr} contiene l'indirizzo internet dell'altro capo
 della comunicazione, e viene acceduto sia come struttura (un resto di una
-implementazione precedente in cui questa era una \texttt{union} usata per accedere alle
-diverse classi di indirizzi) che come intero. 
+implementazione precedente in cui questa era una \texttt{union} usata per
+accedere alle diverse classi di indirizzi) che come intero.
 
 Infine è da sottolineare che sia gli indirizzi che i numeri di porta devono
 essere specificati in quello che viene chiamato \textit{network order}, cioè
@@ -387,6 +422,7 @@ necessit
 portabilità del codice (vedi \secref{sec:sock_addr_func} per i dettagli del
 problema e le relative soluzioni).
 
+
 \subsection{La struttura degli indirizzi IPv6}
 \label{sec:sock_sa_ipv6}
 
@@ -395,7 +431,7 @@ sostanzialmente identici ai precedenti; la parte in cui si trovano
 praticamente tutte le differenze è quella della struttura degli indirizzi. La
 struttura degli indirizzi è definita ancora in \texttt{netinet/in.h}.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
   \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 struct sockaddr_in6 {
@@ -442,7 +478,7 @@ funzione \texttt{socketpair}. Quando per
 ad uno di questi socket si deve usare la seguente struttura di indirizzi
 definita nel file di header \texttt{sys/un.h}.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
   \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 #define UNIX_PATH_MAX    108
@@ -483,6 +519,7 @@ vengono usati i restanti bytes come stringa (senza terminazione).
 % \texttt{getpeername} invece ricevono i valori del kernel 
 
 
+
 \section{Le funzioni di conversione degli indirizzi}
 \label{sec:sock_addr_func}
 
@@ -541,29 +578,29 @@ sul computer e quello che viene usato nelle trasmissione sulla rete; queste
 funzioni sono:
 \begin{prototype}{netinet/in.h}
 {unsigned long int htonl(unsigned long int hostlong)} 
-  Converte l'intero a 32 bit \texttt{hostlong} dal formato della macchina a
+  Converte l'intero a 32 bit \var{hostlong} dal formato della macchina a
   quello della rete.
 \end{prototype}
 \begin{prototype}{netinet/in.h}
 {unsigned short int htons(unsigned short int hostshort)}
-  Converte l'intero a 16 bit \texttt{hostshort} dal formato della macchina a
+  Converte l'intero a 16 bit \var{hostshort} dal formato della macchina a
   quello della rete.
 \end{prototype}
 \begin{prototype}{netinet/in.h}
 {unsigned long int ntonl(unsigned long int netlong)}
-  Converte l'intero a 32 bit \texttt{netlong} dal formato della rete a quello
+  Converte l'intero a 32 bit \var{netlong} dal formato della rete a quello
   della macchina.
 \end{prototype}
 \begin{prototype}{netinet/in.h}
 {unsigned sort int ntons(unsigned short int netshort)}
-  Converte l'intero a 16 bit \texttt{netshort} dal formato della rete a quello
+  Converte l'intero a 16 bit \var{netshort} dal formato della rete a quello
   della macchina.
 \end{prototype}
 I nomi sono assegnati usando la lettera $n$ come mnemonico per indicare
 l'ordinamento usato sulla rete (da \textit{network order}) e la lettera $h$
 come mnemonico per l'ordinamento usato sulla macchina locale (da \textit{host
   order}), mentre le lettere $s$ e $l$ stanno ad indicare i tipi di dato
-(\texttt{long} o \texttt{short}, riportati anche dai prototipi).
+(\type{long} o \type{short}, riportati anche dai prototipi).
 
 Usando queste funzioni si ha la conversione automatica (nel caso pure la
 macchina sia in big endian queste funzioni sono definite come macro che non
@@ -571,8 +608,8 @@ fanno nulla); esse vanno sempre utilizzate per assicurare la portabilit
 codice su tutte le architetture.
 
 
-\subsection{Le funzioni \texttt{inet\_aton}, \texttt{inet\_addr} e 
-  \texttt{inet\_ntoa}}
+\subsection{Le funzioni \func{inet\_aton}, \func{inet\_addr} e 
+  \func{inet\_ntoa}}
 \label{sec:sock_func_ipv4}
 
 Un secondo insieme di funzioni di manipolazione serve per passare dal formato
@@ -587,17 +624,17 @@ cosiddetta notazione \textit{dotted-decimal}, (cio
 indicare la stringa. Dette funzioni sono:
 \begin{prototype}{arpa/inet.h}
   {int inet\_aton(const char *src, struct in\_addr *dest)} Converte la stringa
-  puntata da \texttt{src} nell'indirizzo binario da memorizzare all'indirizzo
-  puntato da \texttt{dest}, restituendo 0 in caso di successo e 1 in caso di
+  puntata da \var{src} nell'indirizzo binario da memorizzare all'indirizzo
+  puntato da \var{dest}, restituendo 0 in caso di successo e 1 in caso di
   fallimento (è espressa in questa forma in modo da poterla usare direttamente
   con il puntatore usato per passare la struttura degli indirizzi). Se usata
-  con \texttt{dest} inizializzato a \texttt{NULL} effettua la validazione
+  con \var{dest} inizializzato a \macro{NULL} effettua la validazione
   dell'indirizzo.
 \end{prototype}
 \begin{prototype}{arpa/inet.h}{in\_addr\_t inet\_addr(const char *strptr)}
   Restituisce l'indirizzo a 32 bit in network order a partire dalla stringa
   passata come parametro, in caso di errore restituisce il valore
-  \texttt{INADDR\_NONE} che tipicamente sono trentadue bit a uno; questo
+  \macro{INADDR\_NONE} che tipicamente sono trentadue bit a uno; questo
   comporta che la stringa \texttt{255.255.255.255}, che pure è un indirizzo
   valido, non può essere usata con questa funzione; per questo motivo essa è
   generalmente deprecata in favore della precedente.
@@ -610,12 +647,12 @@ indicare la stringa. Dette funzioni sono:
 \end{prototype}
 
 
-\subsection{Le funzioni \texttt{inet\_pton} e \texttt{inet\_ntop}}
+\subsection{Le funzioni \func{inet\_pton} e \func{inet\_ntop}}
 \label{sec:sock_conv_func_gen}
 
 Le tre funzioni precedenti sono limitate solo ad indirizzi IPv4, per questo
-motivo è preferibile usare le due nuove funzioni \texttt{inet\_pton} e
-\texttt{inet\_ntop} che possono convertire anche gli indirizzi IPv6. Anche in
+motivo è preferibile usare le due nuove funzioni \func{inet\_pton} e
+\func{inet\_ntop} che possono convertire anche gli indirizzi IPv6. Anche in
 questo caso le lettere $n$ e $p$ sono degli mnemonici per ricordare il tipo di
 conversione effettuata e stanno per \textit{presentation} e \textit{numeric}.
 
@@ -635,8 +672,8 @@ al valore \texttt{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i
 seguenti:
 \begin{prototype}{sys/socket.h}
   {int inet\_pton(int af, const char *src, void *addr\_ptr)} Converte la
-  stringa puntata da \texttt{src} nell'indirizzo IP da memorizzare
-  all'indirizzo puntato da \texttt{addr\_ptr}, la funzione restituisce un
+  stringa puntata da \var{src} nell'indirizzo IP da memorizzare
+  all'indirizzo puntato da \var{addr\_ptr}, la funzione restituisce un
   valore positivo in caso di successo, e zero se la stringa non rappresenta un
   indirizzo valido, e negativo se \var{af} specifica una famiglia di indirizzi
   non valida.
@@ -644,18 +681,18 @@ seguenti:
 
 \begin{prototype}{sys/socket.h}
   {char *inet\_ntop(int af, const void *addr\_ptr, char *dest, size\_t len)}
-  Converte la struttura dell'indirizzo puntata da \texttt{addr\_ptr} in una
-  stringa che viene copiata nel buffer puntato dall'indirizzo \texttt{dest};
+  Converte la struttura dell'indirizzo puntata da \var{addr\_ptr} in una
+  stringa che viene copiata nel buffer puntato dall'indirizzo \var{dest};
   questo deve essere preallocato dall'utente e la lunghezza deve essere almeno
-  \texttt{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e
-  \texttt{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve
-  comunque venire specificata attraverso il parametro \texttt{len}.
+  \macro{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e
+  \macro{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve
+  comunque venire specificata attraverso il parametro \var{len}.
  
-  La funzione restituisce un puntatore non nullo a \texttt{dest} in caso di
+  La funzione restituisce un puntatore non nullo a \var{dest} in caso di
   successo e un puntatore nullo in caso di fallimento, in quest'ultimo caso
-  viene settata la variabile \texttt{errno} con il valore \texttt{ENOSPC} in
+  viene settata la variabile \texttt{errno} con il valore \macro{ENOSPC} in
   caso le dimensioni dell'indirizzo eccedano la lunghezza specificata da
-  \texttt{len} o \macro{ENOAFSUPPORT} in caso \var{af} non sia una famiglia di
+  \var{len} o \macro{ENOAFSUPPORT} in caso \var{af} non sia una famiglia di
   indirizzi valida.
 \end{prototype}
 
@@ -669,7 +706,17 @@ Il formato usato per gli indirizzi in formato di presentazione 
 \textit{dotted decimal} per IPv4 e quella descritta in
 \secref{sec:IP_ipv6_notation} per IPv6.
 
-\section{Il comportamento delle funzioni di I/O}
+
+\section{Un esempio di applicazione}
+\label{sec:sock_appplication}
+
+Per evitare di rendere questa introduzione ai socket puramente teorica
+iniziamo con il mostrare un esempio di un client TCP elementare.  Prima di
+passare agli esempi del client e del server, esamimeremo una caratteristica
+delle funzioni di I/O sui socket che ci tornerà utile anche in seguito.
+
+
+\subsection{Il comportamento delle funzioni di I/O}
 \label{sec:sock_io_behav}
 
 Una cosa di cui non sempre si è consapevoli quando si ha a che fare con i
@@ -677,8 +724,8 @@ socket 
 comportamento che avrebbero con i normali files (in particolare questo accade
 per i socket di tipo stream). 
 
-Infatti con i socket può accadere che funzioni come \texttt{read} o
-\texttt{write} possano restituire in input o scrivere in output un numero di
+Infatti con i socket può accadere che funzioni come \func{read} o
+\func{write} possano restituire in input o scrivere in output un numero di
 bytes minore di quello richiesto. Questo è un comportamento normale e non un
 errore, e succede perché si eccede in lettura o scrittura il limite di buffer
 del kernel. 
@@ -767,3 +814,249 @@ Nel caso della lettura se il numero di bytes letti 
 arrivati alla fine del file e pertanto si ritorna senza aver concluso la
 lettura di tutti i bytes richiesti. 
 
+
+
+\subsection{Un primo esempio di client}
+\label{sec:net_cli_sample}
+
+Lo scopo di questo esempio è fornire un primo approccio alla programmazione di
+rete e vedere come si usano le funzioni descritte in precedenza, alcune delle
+funzioni usate nell'esempio saranno trattate in dettaglio nel capitolo
+successivo; qui ci limiteremo a introdurre la nomenclatura senza fornire
+definizioni precise e dettagli di funzionamento che saranno trattati
+estensivamente più avanti.
+
+In \nfig\ è riportata la sezione principale del codice del nostro client
+elementare per il servizio \textit{daytime}, un servizio standard che
+restituisce l'ora locale della macchina a cui si effettua la richiesta.
+
+\begin{figure}[!htbp]
+  \footnotesize
+  \begin{lstlisting}{}
+#include <sys/types.h>   /* predefined types */
+#include <unistd.h>      /* include unix standard library */
+#include <arpa/inet.h>   /* IP addresses conversion utiliites */
+#include <sys/socket.h>  /* socket library */
+#include <stdio.h>       /* include standard I/O library */
+
+int main(int argc, char *argv[])
+{
+    int sock_fd;
+    int i, nread;
+    struct sockaddr_in serv_add;
+    char buffer[MAXLINE];
+     ...
+    /* create socket */
+    if ( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        perror("Socket creation error");
+        return -1;
+    }
+    /* initialize address */
+    memset((void *) &serv_add, 0, sizeof(serv_add)); /* clear server address */
+    serv_add.sin_family = AF_INET;                   /* address type is INET */
+    serv_add.sin_port = htons(13);                   /* daytime post is 13 */
+    /* build address using inet_pton */
+    if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) {
+        perror("Address creation error");
+        return -1;
+    }
+    /* extablish connection */
+    if (connect(sock_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+        perror("Connection error");
+        return -1;
+    }
+    /* read daytime from server */
+    while ( (nread = read(sock_fd, buffer, MAXLINE)) > 0) {
+        buffer[nread]=0;
+        if (fputs(buffer, stdout) == EOF) {          /* write daytime */
+            perror("fputs error");
+            return -1;
+        }
+    }
+    /* error on read */
+    if (nread < 0) {
+        perror("Read error");
+        return -1;
+    }
+    /* normal exit */
+    return 0;
+}
+  \end{lstlisting}
+  \caption{Esempio di codice di un client elementare per il servizio daytime.}
+  \label{fig:net_cli_code}
+\end{figure}
+
+Il sorgente completo del programma (\texttt{ElemDaytimeTCPClient.c}, che
+comprende il trattamento delle opzioni e una funzione per stampare un
+messaggio di aiuto) è allegato alla guida nella sezione dei codici sorgente e
+può essere compilato su una qualunque macchina Linux.
+
+Il programma anzitutto include gli header necessari (\texttt{\small 1--5});
+dopo la dichiarazione delle variabili (\texttt{\small 9--12}) si è omessa
+tutta la parte relativa al trattamento degli argomenti passati dalla linea di
+comando (effettuata con le apposite routines illustrate in
+\capref{sec:proc_opt_handling}).
+
+Il primo passo (\texttt{\small 14--18}) è creare un \textit{socket} IPv4
+(\macro{AF\_INET}), di tipo TCP \macro{SOCK\_STREAM}. La funzione
+\macro{socket} ritorna il descrittore che viene usato per identificare il
+socket in tutte le chiamate successive. Nel caso la chiamata fallisca si
+stampa un errore con la relativa routine e si esce.
+
+Il passo seguente (\texttt{\small 19--27}) è quello di costruire una apposita
+struttura \type{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed
+il numero della porta del servizio. Il primo passo è inizializzare tutto a
+zero, per poi inserire il tipo di protocollo e la porta (usando per
+quest'ultima la funzione \func{htons} per convertire il formato dell'intero
+usato dal computer a quello usato nella rete), infine si utilizza la funzione
+\texttt{inet\_pton} per convertire l'indirizzo numerico passato dalla linea di
+comando.
+
+Usando la funzione \func{connect} sul socket creato in precedenza
+(\texttt{\small 28--32}) si provvede poi a stabilire la connessione con il
+server specificato dall'indirizzo immesso nella struttura passata come secondo
+argomento, il terzo argomento è la dimensione di detta struttura. Dato che
+esistono diversi tipi di socket, si è dovuto effettuare un cast della
+struttura inizializzata in precedenza, che è specifica per i socket IPv4.  Un
+valore di ritorno negativo implica il fallimento della connessione.
+
+Completata con successo la connessione il passo successivo (\texttt{\small
+  34--40}) è leggere la data dal socket; il server invierà sempre una stringa
+di 26 caratteri della forma \verb|Wed Apr 4 00:53:00 2001\r\n|, che viene
+letta dalla funzione \func{read} e scritta su \texttt{stdout}.
+
+Dato il funzionamento di TCP la risposta potrà tornare in un unico pacchetto
+di 26 byte (come avverrà senz'altro nel caso in questione) ma potrebbe anche
+arrivare in 26 pacchetti di un byte.  Per questo nel caso generale non si può
+mai assumere che tutti i dati arrivino con una singola lettura, pertanto
+quest'ultima deve essere effettuata in un loop in cui si continui a leggere
+fintanto che la funzione \func{read} non ritorni uno zero (che significa che
+l'altro capo ha chiuso la connessione) o un numero minore di zero (che
+significa un errore nella connessione).
+
+Si noti come in questo caso la fine dei dati sia specificata dal server che
+chiude la connessione; questa è una delle tecniche possibili (è quella usata
+pure dal protocollo HTTP), ma ce ne possono essere altre, ad esempio FTP marca
+la conclusione di un blocco di dati con la sequenza ASCII \verb|\r\n|
+(carriage return e line feed), mentre il DNS mette la lunghezza in testa ad
+ogni blocco che trasmette. Il punto essenziale è che TCP non provvede nessuna
+indicazione che permetta di marcare dei blocchi di dati, per cui se questo è
+necessario deve provvedere il programma stesso.
+
+\subsection{Un primo esempio di server}
+\label{sec:net_serv_sample}
+
+Dopo aver illustrato il client daremo anche un esempio di un server
+elementare, in grado di rispondere al precedente client. Il listato è
+nuovamente mostrato in \nfig, il sorgente completo
+(\texttt{ElemDaytimeTCPServer.c}) è allegato insieme agli altri file nella
+directory \texttt{sources}.
+
+\begin{figure}[!htbp]
+  \footnotesize
+  \begin{lstlisting}{}
+#include <sys/types.h>   /* predefined types */
+#include <unistd.h>      /* include unix standard library */
+#include <arpa/inet.h>   /* IP addresses conversion utiliites */
+#include <sys/socket.h>  /* socket library */
+#include <stdio.h>       /* include standard I/O library */
+#include <time.h>
+#define MAXLINE 80
+#define BACKLOG 10
+int main(int argc, char *argv[])
+{
+/* 
+ * Variables definition  
+ */
+    int list_fd, conn_fd;
+    int i;
+    struct sockaddr_in serv_add;
+    char buffer[MAXLINE];
+    time_t timeval;
+    ...
+    /* create socket */
+    if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+        perror("Socket creation error");
+        exit(-1);
+    }
+    /* initialize address */
+    memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
+    serv_add.sin_family = AF_INET;                  /* address type is INET */
+    serv_add.sin_port = htons(13);                  /* daytime port is 13 */
+    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
+    /* bind socket */
+    if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+        perror("bind error");
+        exit(-1);
+    }
+    /* listen on socket */
+    if (listen(list_fd, BACKLOG) < 0 ) {
+        perror("listen error");
+        exit(-1);
+    }
+    /* write daytime to client */
+    while (1) {
+        if ( (conn_fd = accept(list_fd, (struct sockaddr *) NULL, NULL)) <0 ) {
+            perror("accept error");
+            exit(-1);
+        }
+        timeval = time(NULL);
+        snprintf(buffer, sizeof(buffer), "%.24s\r\n", ctime(&timeval));
+        if ( (write(conn_fd, buffer, strlen(buffer))) < 0 ) {
+            perror("write error");
+            exit(-1);
+        }
+        close(conn_fd);
+    }
+    /* normal exit */
+    exit(0);
+}
+  \end{lstlisting}
+  \caption{Esempio di codice di un semplice server per il servizio daytime.}
+  \label{fig:net_serv_code}
+\end{figure}
+
+Come per il client si includono gli header necessari a cui è aggiunto quello
+per trattare i tempi, e si definiscono alcune costanti e le variabili
+necessarie in seguito (\texttt{\small 1--18}), come nel caso precedente si
+sono omesse le parti relative al trattamento delle opzioni da riga di comando.
+
+La creazione del socket (\texttt{\small 22--26}) è analoga al caso precedente,
+come pure l'inizializzazione della struttura \type{sockaddr\_in}, anche in
+questo caso si usa la porta standard del servizio daytime, ma come indirizzo
+IP si il valore predefinito \macro{INET\_ANY} che corrisponde ad un indirizzo
+generico (\texttt{\small 27--31}).
+
+Si effettua poi (\texttt{\small 32--36}) la chiamata alla funzione
+\func{bind} che permette di associare la precedente struttura al socket, in
+modo che quest'ultimo possa essere usato per accettare connessioni su una
+qualunque delle interfacce di rete locali.
+
+Il passo successivo (\texttt{\small 37--41}) è mettere ``in ascolto'' il
+socket, questo viene effettuato con la funzione \func{listen} che dice al
+kernel di accettare connessioni per il socket specificato, la funzione indica
+inoltre, con il secondo parametro, il numero massimo di connessioni che il
+kernel accetterà di mettere in coda per il suddetto socket.
+
+Questa ultima chiamata completa la preparazione del socket per l'ascolto (che
+viene chiamato anche \textit{listening descriptor}) a questo punto il processo
+è mandato in sleep (\texttt{\small 44--47}) con la successiva chiamata alla
+funzione \func{accept}, fin quando non arriva e viene accettata una
+connessione da un client.
+
+Quando questo avviene \func{accept} ritorna un secondo descrittore di socket,
+che viene chiamato \textit{connected descriptor} che è quello che viene usato
+dalla successiva chiamata alla \func{write} per scrivere la risposta al
+client, una volta che si è opportunamente (\texttt{\small 48--49}) costruita
+la stringa con la data da trasmettere. Completata la trasmissione il nuovo
+socket viene chiuso (\texttt{\small 54}).  Il tutto è inserito in un loop
+infinito (\texttt{\small 42--55}) in modo da poter ripetere l'invio della data
+ad una successiva connessione.
+
+È importante notare che questo server è estremamente elementare, infatti a
+parte il fatto di essere dipendente da IPv4, esso è in grado di servire solo
+un client alla volta, è cioè un \textsl{server iterativo}, inoltre esso è
+scritto per essere lanciato da linea di comando, se lo si volesse utilizzare
+come demone di sistema (che è in esecuzione anche quando non c'è nessuna shell
+attiva e il terminale da cui lo si è lanciato è stato sconnesso),
+occorrerebbero delle opportune modifiche.