Aggiunti alcuni header alla lista e quattro chiacchiere sulle alternative
[gapil.git] / socket.tex
index ecf1a9eeb826183a1a6377e0cf76e52a1630e59a..ef729a56eb0e35ae88b95d02b57f4e7c911696f1 100644 (file)
@@ -1,11 +1,33 @@
 \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
+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 un'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{presa}, 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 (vedi \secref{sec:ipc_pipes}) 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.
@@ -14,10 +36,10 @@ Quella dei socket costituisce infatti la principale API (\textit{Application
   Program Interface}) usata nella programmazione di rete.  La loro origine
 risale al 1983, quando furono introdotti nel BSD 4.2; l'interfaccia è rimasta
 sostanzialmente la stessa con piccole modifiche negli anni successivi. Benché
-siano state sviluppate interfacce alternative, originate dai sistemi SYSV,
+siano state sviluppate interfacce alternative, originate dai sistemi SVr4,
 come la XTI (\textit{X/Open Transport Interface}) nessuna ha mai raggiunto la
-diffusione e la popolarità di quella dei socket (né tantomeno usabilità e
-flessibilità).
+diffusione e la popolarità di quella dei socket (né tantomeno la stessa
+usabilità e flessibilità).
 
 La flessibilità e la genericità dell'interfaccia inoltre ha consentito di
 utilizzare i socket con i più disparati meccanismi di comunicazione, e non
@@ -25,7 +47,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
@@ -36,15 +58,15 @@ usato, le funzioni da usare restano le stesse.
 
 Per questo motivo una semplice descrizione dell'interfaccia è assolutamente
 inutile, in quanto il comportamento di quest'ultima e le problematiche da
-affrontare cambiano radicalmente a seconda dello ``stile'' di comunicazione
-usato.  La scelta di questo stile va infatti ad incidere sulla semantica che
-verrà utilizzata a livello utente per gestire la comunicazione (su come
-inviare e ricevere i dati) e sul comportamento effettivo delle funzioni
-utilizzate.
+affrontare cambiano radicalmente a seconda dello \textsl{stile} di
+comunicazione usato.  La scelta di questo stile va infatti ad incidere sulla
+semantica che verrà utilizzata a livello utente per gestire la comunicazione
+(su come inviare e ricevere i dati) e sul comportamento effettivo delle
+funzioni utilizzate.
 
 La scelta di uno stile dipende sia dai meccanismi disponibili, sia dal tipo di
 comunicazione che si vuole effettuare. Ad esempio alcuni stili di
-comunicazione considerano i dati come una sequenza continua di bytes, altri
+comunicazione considerano i dati come una sequenza continua di byte, altri
 invece li raggruppano in blocchi (i pacchetti).
 
 Un'altro esempio di stile concerne la possibilità che la comunicazione possa o
@@ -64,13 +86,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 \func{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
+\func{socket} questa restituisce un \textit{socket descriptor} (un valore
+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!]).
@@ -82,23 +112,25 @@ protocollo; in genere quest'ultimo 
 socket, per cui viene messo a zero (con l'eccezione dei \textit{raw socket}).
 
 \begin{prototype}{sys/socket.h}{int socket(int domain, int type, int protocol)}
+
+  Apre un socket.
   
-  La funzione restituisce un intero positivo se riesce, e -1 se fallisce, in
-  quest'ultimo caso la variabile \texttt{errno} è settata con i seguenti
-  codici di errore:
+  \bodydesc{La funzione restituisce un intero positivo se riesce, e -1 se
+    fallisce, in quest'ultimo caso la variabile \var{errno} è impostata con i
+    seguenti codici di errore:
 
   \begin{errlist}
-  \item \texttt{EPROTONOSUPPORT} Il tipo di socket o il protocollo scelto non
+  \item[\macro{EPROTONOSUPPORT}] Il tipo di socket o il protocollo scelto non
     sono supportati nel dominio.
-  \item \texttt{ENFILE} Il kernel non ha memoria sufficiente a creare una
+  \item[\macro{ENFILE}] Il kernel non ha memoria sufficiente a creare una
     nuova struttura per il socket.
-  \item \texttt{EMFILE} Si è ecceduta la tabella dei file.
-  \item \texttt{EACCES} Non si hanno privilegi per creare un socket nel
+  \item[\macro{EMFILE}] Si è ecceduta la tabella dei file.
+  \item[\macro{EACCES}] Non si hanno privilegi per creare un socket nel
     dominio o con il protocollo specificato.
-  \item \texttt{EINVAL} Protocollo sconosciuto o dominio non disponibile.
-  \item \texttt{ENOBUFS} o \texttt{ENOMEM} Non c'è sufficiente memoria per
-    creare il socket.
-  \end{errlist}
+  \item[\macro{EINVAL}] Protocollo sconosciuto o dominio non disponibile.
+  \item[\macro{ENOBUFS}] Non c'è sufficiente memoria per creare il socket (può
+    essere anche \macro{ENOMEM}).
+  \end{errlist}}
 \end{prototype}
 
 Si noti che la creazione del socket non comporta nulla riguardo
@@ -117,9 +149,10 @@ altro nome con cui si indicano i domini.
 
 A ciascun tipo di dominio corrisponde un analogo nome simbolico che inizia per
 \texttt{AF\_} da \textit{address family}, e che identifica il formato degli
-indirizzi usati in quel dominio; le man pages di linux si riferiscono a questi
-anche come \textit{name space}, (nome che però il manuale della glibc riserva
-ai domini) e che identifica il formato degli indirizzi usati in quel dominio.
+indirizzi usati in quel dominio; le pagine di manuale di Linux si riferiscono
+a questi anche come \textit{name space}, (nome che però il manuale delle
+\acr{glibc} riserva ai domini) e che identifica il formato degli indirizzi
+usati in quel dominio.
 
 L'idea alla base della distinzione era che una famiglia di protocolli potesse
 supportare vari tipi di indirizzi, per cui il prefisso \texttt{PF\_} si
@@ -130,34 +163,38 @@ supportino diverse strutture di indirizzi, per cui nella pratica questi due
 nomi sono equivalenti e corrispondono agli stessi valori.
 
 I domini (e i relativi nomi simbolici), così come i nomi delle famiglie di
-indirizzi sono definiti dall'header \textit{socket.h}. In linux le famiglie di
-protocolli disponibili sono riportate in \ntab.
+indirizzi sono definiti dall'header \textit{socket.h}. In Linux le famiglie di
+protocolli disponibili sono riportate in \tabref{tab:net_pf_names}.
 
 \begin{table}[htb]
   \footnotesize
   \centering
-  \begin{tabular}[c]{lll}
-       Nome               & Utilizzo                       & Man page   \\
+  \begin{tabular}[c]{|l|l|l|}
+       \hline
+       \textbf{Nome}      & \textbf{Utilizzo}           &\textbf{Man page} \\
+       \hline
+       \hline
+       \macro{PF\_UNIX},
+       \macro{PF\_LOCAL}  & Local communication            & unix(7)    \\
+       \macro{PF\_INET}   & IPv4 Internet protocols        & ip(7)      \\
+       \macro{PF\_INET6}  & IPv6 Internet protocols        & ipv6(7)    \\
+       \macro{PF\_IPX}    & IPX - Novell protocols         &            \\
+       \macro{PF\_NETLINK}& Kernel user interface device   & netlink(7) \\
+       \macro{PF\_X25}    & ITU-T X.25 / ISO-8208 protocol & x25(7)     \\
+       \macro{PF\_AX25}   & Amateur radio AX.25 protocol   &            \\
+       \macro{PF\_ATMPVC} & Access to raw ATM PVCs         &            \\
+       \macro{PF\_APPLETALK}& Appletalk                    & ddp(7)     \\
+       \macro{PF\_PACKET} & Low level packet interface     & packet(7)  \\    
        \hline
-       PF\_UNIX,PF\_LOCAL & Local communication            & unix(7)    \\
-       PF\_INET           & IPv4 Internet protocols        & ip(7)      \\
-       PF\_INET6          & IPv6 Internet protocols        &            \\
-       PF\_IPX            & IPX - Novell protocols         &            \\
-       PF\_NETLINK        & Kernel user interface device   & netlink(7) \\
-       PF\_X25            & ITU-T X.25 / ISO-8208 protocol & x25(7)     \\
-       PF\_AX25           & Amateur radio AX.25 protocol   &            \\
-       PF\_ATMPVC         & Access to raw ATM PVCs         &            \\
-       PF\_APPLETALK      & Appletalk                      & ddp(7)     \\
-       PF\_PACKET         & Low level packet interface     & packet(7)  \\    
   \end{tabular}
-  \caption{Famiglie di protocolli definiti in linux}
+  \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
-creati solo da processi che hanno i provilegi di root (cioè effective uid
-uguale a zero) o la capability \texttt{CAP\_NET\_RAW}.
+esempio in generale tutti i socket di tipo \macro{SOCK\_RAW} possono essere
+creati solo da processi che hanno i privilegi di root (cioè con userid
+effettivo uguale a zero) o con la capability \macro{CAP\_NET\_RAW}.
 
 
 \subsection{Il tipo, o stile}
@@ -166,73 +203,79 @@ uguale a zero) o la capability \texttt{CAP\_NET\_RAW}.
 La scelta di un dominio non comporta però la scelta dello stile di
 comunicazione, questo infatti viene a dipendere dal protocollo che si andrà ad
 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}:
+scegliere lo stile di comunicazione indicando il tipo di socket; Linux e le
+\acr{glibc} mettono a disposizione i seguenti tipi di socket (che il manuale
+della \acr{glibc} chiama \textit{styles}) definiti come \ctyp{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
-tipo di socket sono valide, in quanto non è detto che nella famiglia esista un
-protocollo per tutti gli stili di comunicazione indicati qui sopra. Una
-tabella che mostra le combinazioni valide è la seguente:
+Si tenga presente che non tutte le combinazioni fra una famiglia di protocolli
+e un tipo di socket sono valide, in quanto non è detto che in una famiglia
+esista un protocollo per ciascuno dei diversi stili di comunicazione appena
+elencati.
 
 \begin{table}[htb]
   \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}
 
-Dove per ogni combinazione valida si è indicato il tipo di protocollo, o la
-parola \textsl{si} qualora non il protocollo non abbia un nome definito,
-mentre si sono lasciate vuote le caselle per le combinazioni non supportate.
+In \secref{tab:sock_sock_valid_combinations} sono mostrate le combinazioni
+valide possibili per le varie famiglie di protocolli. Per ogni combinazione
+valida si è indicato il tipo di protocollo, o la 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}
@@ -249,10 +292,11 @@ viene effettivamente realizzata.
 
 Ogni famiglia di protocolli ha ovviamente una sua forma di indirizzamento e in
 corrispondenza a questa una sua peculiare struttura degli indirizzi; i nomi di
-tutte queste strutture iniziano per \texttt{sockaddr\_}, quelli propri di
+tutte queste strutture iniziano per \var{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,20 +305,20 @@ 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
-definizione dello standard ANSI, e per questo nel 1982 fu scelto di definire
-una struttura generica \texttt{sockaddr} per gli indirizzi dei socket mostrata
-in \nfig:
+(i \ctyp{void *}), ma l'interfaccia dei socket è antecedente alla definizione
+dello standard ANSI, e per questo nel 1982 fu scelto di definire una struttura
+generica per gli indirizzi dei socket, \type{sockaddr}, che si è riportata in
+\figref{fig:sock_sa_gen_struct}.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
-  \begin{lstlisting}{}
+  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 struct sockaddr {
     sa_family_t  sa_family;     /* address family: AF_xxx */
     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}
 
@@ -284,51 +328,52 @@ invocano dette funzioni passando l'indirizzo di un protocollo specifico
 occorrerà eseguire un casting del relativo puntatore.
 
 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}
+POSIX.1g, riassunti in \tabref{tab:sock_data_types} con i rispettivi file di
+include in cui sono definiti; la struttura è invece definita nell'include file
+\file{sys/socket.h}.
 
-\begin{table}[!htbp]
+\begin{table}[!htb]
   \centering
   \begin{tabular}{|l|l|l|}
     \hline
-    \multicolumn{1}{|c|}{Tipo}& \multicolumn{1}{|c|}{Descrizione}& 
-    \multicolumn{1}{|c|}{Header} \\
+    \multicolumn{1}{|c|}{\textbf{Tipo}}& 
+    \multicolumn{1}{|c|}{\textbf{Descrizione}}& 
+    \multicolumn{1}{|c|}{\textbf{Header}} \\
     \hline
     \hline
-    \texttt{int8\_t}   & intero a 8 bit con segno   & \texttt{sys/types.h}\\
-    \texttt{uint8\_t}  & intero a 8 bit senza segno & \texttt{sys/types.h}\\
-    \texttt{int16\_t}  & intero a 16 bit con segno  & \texttt{sys/types.h}\\
-    \texttt{uint16\_t} & intero a 16 bit senza segno& \texttt{sys/types.h}\\
-    \texttt{int32\_t}  & intero a 32 bit con segno  & \texttt{sys/types.h}\\
-    \texttt{uint32\_t} & intero a 32 bit senza segno& \texttt{sys/types.h}\\
+    \type{int8\_t}   & intero a 8 bit con segno   & \file{sys/types.h}\\
+    \type{uint8\_t}  & intero a 8 bit senza segno & \file{sys/types.h}\\
+    \type{int16\_t}  & intero a 16 bit con segno  & \file{sys/types.h}\\
+    \type{uint16\_t} & intero a 16 bit senza segno& \file{sys/types.h}\\
+    \type{int32\_t}  & intero a 32 bit con segno  & \file{sys/types.h}\\
+    \type{uint32\_t} & intero a 32 bit senza segno& \file{sys/types.h}\\
     \hline
-    \texttt{sa\_family\_t} & famiglia degli indirizzi& \texttt{sys/socket.h}\\
-    \texttt{socklen\_t} & lunghezza (\texttt{uint32\_t}) dell'indirizzo di
-    un socket& \texttt{sys/socket.h}\\
+    \type{sa\_family\_t} & famiglia degli indirizzi& \file{sys/socket.h}\\
+    \type{socklen\_t} & lunghezza (\type{uint32\_t}) dell'indirizzo di
+    un socket& \file{sys/socket.h}\\
     \hline
-    \texttt{in\_addr\_t} & indirizzo IPv4 (\texttt{uint32\_t}) & 
-    \texttt{netinet/in.h}\\
-    \texttt{in\_port\_t} & porta TCP o UDP (\texttt{uint16\_t})& 
-    \texttt{netinet/in.h}\\
+    \type{in\_addr\_t} & indirizzo IPv4 (\type{uint32\_t}) & 
+    \file{netinet/in.h}\\
+    \type{in\_port\_t} & porta TCP o UDP (\type{uint16\_t})& 
+    \file{netinet/in.h}\\
     \hline
   \end{tabular}
   \caption{Tipi di dati usati nelle strutture degli indirizzi, secondo quanto 
-    stabilito dallo standard Posix.1g}
+    stabilito dallo standard POSIX.1g.}
   \label{tab:sock_data_types}
 \end{table}
 
 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
+aggiuntivo \var{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 \ctyp{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'
 diverse, in quanto esso usa il puntatore per recuperare il campo
-\texttt{sa\_family} con cui determinare il tipo di indirizzo; per questo
-motivo, anche se l'uso di un puntatore \texttt{void *} sarebbe più immediato
+\var{sa\_family} con cui determinare il tipo di indirizzo; per questo
+motivo, anche se l'uso di un puntatore \ctyp{void *} sarebbe più immediato
 per l'utente (che non dovrebbe più eseguire il casting), è stato mantenuto
 l'uso di questa struttura.
 
@@ -336,16 +381,15 @@ 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
-\texttt{netinet/in.h} e secondo le man page ha la forma mostrata in \nfig,
-conforme allo standard Posix.1g.
+(IPv4) è definita come \type{sockaddr\_in} nell'header file
+\file{netinet/in.h} e secondo le pagine di manuale ha la forma mostrata in
+\figref{fig:sock_sa_ipv4_struct}, conforme allo standard POSIX.1g.
 
-
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
-  \begin{lstlisting}{}
+  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 struct sockaddr_in {
     sa_family_t     sin_family; /* address family: AF_INET */
     u_int16_t       sin_port;   /* port in network byte order */
@@ -357,7 +401,7 @@ struct in_addr {
 };
   \end{lstlisting}
   \caption{La struttura degli indirizzi dei socket internet (IPv4)
-    \texttt{sockaddr\_in}.}
+    \type{sockaddr\_in}.}
   \label{fig:sock_sa_ipv4_struct}
 \end{figure}
 
@@ -366,19 +410,19 @@ internet di un'interfaccia pi
 prevede numeri di porta, che sono utilizzati solo dai protocolli di livello
 superiore come TCP e UDP. Questa struttura però viene usata anche per i socket
 RAW che accedono direttamente al livello di IP, nel qual caso il numero della
-porta viene settato al numero di protocollo.
+porta viene impostato al numero di protocollo.
 
-Il membro \texttt{sin\_family} deve essere sempre settato; \texttt{sin\_port}
+Il membro \var{sin\_family} deve essere sempre impostato; \var{sin\_port}
 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.
+servizi standard. Soltanto processi con i privilegi di root (con userid
+effettivo uguale a zero) o con la capability \macro{CAP\_NET\_BIND\_SERVICE}
+possono usare la funzione \func{bind} su queste porte.
 
-Il membro \texttt{sin\_addr} contiene l'indirizzo internet dell'altro capo
+Il membro \var{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 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,17 +431,18 @@ 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}
 
-Essendo IPv6 una estenzione di IPv4 i socket di tipo \texttt{PF\_INET6} sono
+Essendo IPv6 un'estensione di IPv4 i socket di tipo \macro{PF\_INET6} sono
 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}.
+struttura degli indirizzi è definita ancora in \file{netinet/in.h}.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
-  \begin{lstlisting}{}
+  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 struct sockaddr_in6 {
     u_int16_t       sin6_family;   /* AF_INET6 */
     u_int16_t       sin6_port;     /* port number */
@@ -411,23 +456,23 @@ struct in6_addr {
 };
   \end{lstlisting}
   \caption{La struttura degli indirizzi dei socket IPv6 
-    \texttt{sockaddr\_in6}.}
+    \type{sockaddr\_in6}.}
   \label{fig:sock_sa_ipv6_struct}
 \end{figure}
 
-Il campo \texttt{sin6\_family} deve essere sempre settato ad
-\texttt{AF\_INET6}, il campo \texttt{sin6\_port} è analogo a quello di IPv4 e
-segue le stesse regole; il campo \texttt{sin6\_flowinfo} è a dua volta diviso
+Il campo \var{sin6\_family} deve essere sempre impostato ad
+\macro{AF\_INET6}, il campo \var{sin6\_port} è analogo a quello di IPv4 e
+segue le stesse regole; il campo \var{sin6\_flowinfo} è a sua volta diviso
 in tre parti di cui i 24 bit inferiori indicano l'etichetta di flusso, i
 successivi 4 bit la priorità e gli ultimi 4 sono riservati; questi valori
 fanno riferimento ad alcuni campi specifici dell'header dei pacchetti IPv6
-(vedi \secref{sec:appA_ipv6}) ed il loro uso è sperimentale.
+(vedi \secref{sec:IP_ipv6head}) ed il loro uso è sperimentale.
 
-Il campo \texttt{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6,
-infine il campo \texttt{sin6\_scope\_id} è un campo introdotto con il kernel
+Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6,
+infine il campo \var{sin6\_scope\_id} è un campo introdotto con il kernel
 2.4 per gestire alcune operazioni riguardanti il multicasting.
  
-Si noti che questa struttura è più grande di una \texttt{sockaddr} generica,
+Si noti che questa struttura è più grande di una \var{sockaddr} generica,
 quindi occorre stare attenti a non avere fatto assunzioni riguardo alla
 possibilità di contenere i dati nelle dimensioni di quest'ultima.
 
@@ -435,16 +480,17 @@ possibilit
 \subsection{La struttura degli indirizzi locali}
 \label{sec:sock_sa_local}
 
-I socket di tipo \texttt{PF\_UNIX} vengono usati per una comunicazione
-efficiente fra processi che stanno sulla stessa macchina; essi rispetto ai
+I socket di tipo \macro{PF\_UNIX} o \macro{PF\_LOCAL} vengono usati per una
+comunicazione fra processi che stanno sulla stessa macchina (per vengono
+chiamati \textit{local domain} o anche \textit{Unix domain}); essi rispetto ai
 precedenti possono essere anche creati in maniera anonima attraverso la
-funzione \texttt{socketpair}. Quando però si vuole fare riferimento esplicito
-ad uno di questi socket si deve usare la seguente struttura di indirizzi
-definita nel file di header \texttt{sys/un.h}.
+funzione \func{socketpair} (vedi \secref{sec:ipc_socketpair}). Quando però si
+vuole fare riferimento esplicito ad uno di questi socket si deve usare la
+seguente struttura di indirizzi definita nel file di header \file{sys/un.h}.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize
-  \begin{lstlisting}{}
+  \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
 #define UNIX_PATH_MAX    108
 struct sockaddr_un {
     sa_family_t  sun_family;              /* AF_UNIX */
@@ -452,17 +498,17 @@ struct sockaddr_un {
 };
   \end{lstlisting}
   \caption{La struttura degli indirizzi dei socket locali 
-    \texttt{sockaddr\_un}.}
+    \var{sockaddr\_un}.}
   \label{fig:sock_sa_local_struct}
 \end{figure}
 
-In questo caso il campo \texttt{sun\_family} deve essere \texttt{AF\_UNIX},
-mentre il campo \texttt{sun\_path} deve specificare un indirizzo; questo ha
+In questo caso il campo \var{sun\_family} deve essere \macro{AF\_UNIX},
+mentre il campo \var{sun\_path} deve specificare un indirizzo; questo ha
 due forme un file (di tipo socket) nel filesystem o una stringa univoca
 (tenuta in uno spazio di nomi astratto). Nel primo caso l'indirizzo viene
 specificato come una stringa (terminata da uno zero) corrispondente al
-pathname del file; nel secondo invece \texttt{sun\_path} inizia con uno zero
-vengono usati i restanti bytes come stringa (senza terminazione).
+pathname del file; nel secondo invece \var{sun\_path} inizia con uno zero
+vengono usati i restanti byte come stringa (senza terminazione).
 
 
 % \subsection{Il passaggio delle strutture}
@@ -483,6 +529,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}
 
@@ -498,7 +545,7 @@ utile anche in seguito.
 \subsection{La \textit{endianess}}
 \label{sec:sock_endianess}
 
-La rappresentazione di un numbero binario in un computer può essere fatta in
+La rappresentazione di un numero binario in un computer può essere fatta in
 due modi, chiamati rispettivamente \textit{big endian} e \textit{little
   endian} a seconda di come i singoli bit vengono aggregati per formare le
 variabili intere (in diretta corrispondenza a come sono poi in realtà cablati
@@ -515,23 +562,27 @@ numero. Il caso opposto, in cui si parte dal bit meno significativo 
 per lo stesso motivo \textit{big endian}.
 
 La \textit{endianess} di un computer dipende essenzialmente dalla architettura
-hardware usata; intel e digital usano il little endian, motorola, ibm, sun
-(sostanzialmente tutti gli altri) usano il big endian. Il formato della rete è
-anch'esso big endian. Esistono poi anche dei processori che possono scegliere
-il tipo di formato all'avvio e alcuni, come il PowerPC o l'intel i860, possono
-pure passare da un tipo all'altro con una specifica istruzione; in ogni caso
-in linux l'ordinamanento è definito dall'archiettura e anche se questi
-cambiamenti sono possibili anche dopo che il sistema è avviato, non vengono
-mai eseguiti.
+hardware usata; Intel e Digital usano il \textit{little endian}, Motorola,
+IBM, Sun (sostanzialmente tutti gli altri) usano il \textit{big endian}. Il
+formato della rete è anch'esso \textit{big endian}, altri esempi sono quello
+del bus PC, che è \textit{little endian}, o quello del bus VME che è
+\textit{big endian}.
+
+Esistono poi anche dei processori che possono scegliere il tipo di formato
+all'avvio e alcuni che, come il PowerPC o l'Intel i860, possono pure passare
+da un tipo di ordinamento all'altro con una specifica istruzione. In ogni caso
+in Linux l'ordinamento è definito dall'architettura e dopo l'avvio del sistema
+resta sempre lo stesso, anche quando il processore permetterebbe di eseguire
+questi cambiamenti.
 
 \subsection{Le funzioni per il riordinamento}
 \label{sec:sock_func_ord}
 
 Il problema connesso all'endianess è che quando si passano dei dati da un tipo
 di architettura all'altra i dati vengono interpretati in maniera diversa, e ad
-esempio nel caso dell'intero a 16 bit ci si ritroverà con i due bytes in cui è
+esempio nel caso dell'intero a 16 bit ci si ritroverà con i due byte in cui è
 suddiviso scambiati di posto, e ne sarà quindi invertito l'ordine di lettura
-per cui, per riavere il valore originale dovrenno essere rovesciati.
+per cui, per riavere il valore originale dovranno essere rovesciati.
 
 Per questo motivo si usano le seguenti funzioni di conversione che servono a
 tener conto automaticamente della possibile differenza fra l'ordinamento usato
@@ -539,122 +590,148 @@ 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 sort int htons(unsigned short int hostshort)}
-  Converte l'intero a 16 bit \texttt{hostshort} dal formato della macchina a
+{unsigned short int htons(unsigned short int hostshort)}
+  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).
-
-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
-fanno nulla); esse vanno sempre utilizzate per assicurare la portabilità del
-codice su tutte le architetture.
-
-
-\subsection{Le funzioni \texttt{inet\_aton}, \texttt{inet\_addr} e 
-  \texttt{inet\_ntoa}}
+I nomi sono assegnati usando la lettera \texttt{n} come mnemonico per indicare
+l'ordinamento usato sulla rete (da \textit{network order}) e la lettera
+\texttt{h} come mnemonico per l'ordinamento usato sulla macchina locale (da
+\textit{host order}), mentre le lettere \texttt{s} e \texttt{l} stanno ad
+indicare i tipi di dato (\ctyp{long} o \ctyp{short}, riportati anche dai
+prototipi).
+
+Usando queste funzioni si ha la conversione automatica: nel caso in cui la
+macchina che si sta usando abbia una architettura \textit{big endian} queste
+funzioni sono definite come macro che non fanno nulla. Per questo motivo vanno
+sempre utilizzate, anche quando potrebbero non essere necessarie, in modo da
+assicurare la portabilità del codice su tutte le architetture.
+
+
+\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
 binario usato nelle strutture degli indirizzi alla rappresentazione dei numeri
-IP che si usa normalente.
+IP che si usa normalmente.
 
 Le prime tre funzioni di manipolazione riguardano la conversione degli
 indirizzi IPv4 da una stringa in cui il numero di IP è espresso secondo la
 cosiddetta notazione \textit{dotted-decimal}, (cioè nella forma
 \texttt{192.160.0.1}) al formato binario (direttamente in \textit{network
-  order}) e viceversa; in questo caso si usa la lettera $a$ come mnemonico per
-indicare la stringa. Dette funzioni sono:
+  order}) e viceversa; in questo caso si usa la lettera \texttt{a} come
+mnemonico per 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
-  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
-  dell'indirizzo.
+  {int inet\_aton(const char *src, struct in\_addr *dest)} 
+  Converte la stringa 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 \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.
 \end{prototype}  
 \begin{prototype}{arpa/inet.h}{char *inet\_ntoa(struct in\_addr addrptr)}
-  Converte il valore a 32 bit dell'indirizzo (espresso in network order)
-  restituendo il puntatore alla stringa che contiene l'espressione in formato
-  dotted decimal. Si deve tenere presente che la stringa risiede in memoria
-  statica, per cui questa funzione non è rientrante.
+  Converte il valore a 32 bit dell'indirizzo (espresso in \textit{network
+    order}) restituendo il puntatore alla stringa che contiene l'espressione
+  in formato dotted decimal. Si deve tenere presente che la stringa risiede in
+  memoria statica, per cui questa funzione non è rientrante.
 \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 (secondo
-lo schema in \nfig). 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}.
+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 \texttt{n} e \texttt{p} sono degli mnemonici per
+ricordare il tipo di conversione effettuata e stanno per \textit{presentation}
+e \textit{numeric}.
+
+% \begin{figure}[htb]
+%   \centering  
+
+%   \caption{Schema della rappresentazioni utilizzate dalle funzioni di 
+%     conversione \texttt{inet\_pton} e \texttt{inet\_ntop} }
+%   \label{fig:sock_inet_conv_func}
+
+% \end{figure}
+
+Entrambe le funzioni accettano l'argomento \param{af} che indica il tipo di
+indirizzo e può essere \macro{AF\_INET} o \macro{AF\_INET6}. Se la famiglia
+indicata non è valida entrambe le funzioni impostano la variabile \var{errno}
+al valore \macro{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 \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.
+\end{prototype}
+\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 \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
+  \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}.
+  \bodydesc{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 impostata la variabile \var{errno} con il valore
+    \macro{ENOSPC} in caso le dimensioni dell'indirizzo eccedano la lunghezza
+    specificata da \var{len} o \macro{ENOAFSUPPORT} in caso \var{af} non sia
+    una famiglia di indirizzi valida.}
+\end{prototype}
 
-\begin{figure}[htb]
-  \centering  
+Gli indirizzi vengono convertiti da/alle rispettive strutture di indirizzo
+(\var{struct  in\_addr} per IPv4, e \var{struct  in6\_addr} per IPv6), che
+devono essere precedentemente allocate e passate attraverso il puntatore
+\var{addr\_ptr}; il parametro \var{dest} di \func{inet\_ntop} non può essere
+nullo e deve essere allocato precedentemente.
 
-  \caption{Schema della rappresentazioni utilizzate dalle funzioni di 
-    conversione \texttt{inet\_pton} e \texttt{inet\_ntop} }
-  \label{fig:sock_inet_conv_func}
+Il formato usato per gli indirizzi in formato di presentazione è la notazione
+\textit{dotted decimal} per IPv4 e quella descritta in
+\secref{sec:IP_ipv6_notation} per IPv6.
 
-\end{figure}
 
-Entrambe le funzioni accettano l'argomento \texttt{family} che indica il tipo
-di indirizzo e può essere \texttt{AF\_INET} o \texttt{AF\_INET6}. Se la
-famiglia indicata non è valida entrambe le funzioni ritornano un valore
-negativo e settano la variabile \texttt{errno} al valore
-\texttt{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i seguenti:
-\begin{prototype}{int inet\_pton(int family, const char *src, void *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 fallimento. 
-\end{prototype}
-\begin{prototype}{char *inet\_ntop(int family, const void *src, char *dest,
-    size\_t len)}
-  Converte la struttura dell'indirizzo puntata da \texttt{src} in una stringa
-  che viene copiata nel buffer puntato dall'indirizzo \texttt{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}.
-  
-  La funzione restituisce un puntatore non nullo a \texttt{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
-  caso le dimensioni dell'indirizzo eccedano la lunghezza specificata da
-  \texttt{len}.
-\end{prototype}
+
+\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, esamineremo una caratteristica
+delle funzioni di I/O sui socket che ci tornerà utile anche in seguito.
 
 
-\section{Il comportamento delle funzioni di I/O}
+\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
@@ -662,15 +739,15 @@ 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
-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. 
+Infatti con i socket è comune che funzioni come \func{read} o \func{write}
+possano restituire in input o scrivere in output un numero di byte minore di
+quello richiesto. Come già accennato in \secref{sec:file_read} questo è un
+comportamento normale anche per l'I/O su file, e succede
+perché si eccede in lettura o scrittura il limite di buffer del kernel.
 
 In questo caso tutto quello che il programma chiamante deve fare è di ripetere
-la lettura (o scrittura) per la quantità di bytes rimanenti (lo stesso può
-avvenire scrivendo più di 4096 bytes in una pipe, dato che quello è il limite
+la lettura (o scrittura) per la quantità di byte rimanenti (lo stesso può
+avvenire scrivendo più di 4096 byte in una pipe, dato che quello è il limite
 di solito adottato per il buffer di trasmissione del kernel).
 
 \begin{figure}[htb]
@@ -701,16 +778,17 @@ ssize_t SockRead(int fd, void *buf, size_t count)
     return (count - nleft);
 }  
   \end{lstlisting}
-  \caption{Funzione \texttt{SockRead}, legge $n$ bytes da un socket }
+  \caption{Funzione \func{SockRead}, legge \var{count} byte da un socket }
   \label{fig:sock_SockRead_code}
 \end{figure}
 
 Per questo motivo seguendo l'esempio di W. R. Stevens si sono definite due
-funzioni \texttt{SockRead} e \texttt{SockWrite} che eseguono la lettura da un
+funzioni \func{SockRead} e \func{SockWrite} che eseguono la lettura da un
 socket tenendo conto di questa caratteristica, ed in grado di ritornare dopo
-avere letto o scritto esattamente il numero di bytes specificato; il sorgente
-è riportato in \curfig\ e \nfig\ ed è disponibile fra i sorgenti allegati alla
-guida nei files \texttt{SockRead.c} e \texttt{SockWrite.c}.
+avere letto o scritto esattamente il numero di byte specificato; il sorgente è
+riportato in \figref{fig:sock_SockRead_code} e
+\figref{fig:sock_SockWrite_code} ed è disponibile fra i sorgenti allegati alla
+guida nei files \file{SockRead.c} e \file{SockWrite.c}.
 
 \begin{figure}[htb]
   \centering
@@ -738,17 +816,269 @@ ssize_t SockWrite(int fd, const void *buf, size_t count)
     return (count);
 }  
   \end{lstlisting}
-  \caption{Funzione \texttt{SockWrite}, scrive $n$ bytes su un socket }
+  \caption{Funzione \func{SockWrite}, scrive \var{count} byte su un socket }
   \label{fig:sock_SockWrite_code}
 \end{figure}
 
-Come si può notare le funzioni ripetono la lettura/scrittura in un loop fino
-all'esaurimento del numero di bytes richiesti, in caso di errore viene
-controllato se questo è \texttt{EINTR} (cioè un'interruzione della system call
+Come si può notare le funzioni ripetono la lettura/scrittura in un ciclo fino
+all'esaurimento del numero di byte richiesti, in caso di errore viene
+controllato se questo è \macro{EINTR} (cioè un'interruzione della system call
 dovuta ad un segnale), nel qual caso l'accesso viene ripetuto, altrimenti
-l'errore viene ritornato interrompendo il loop. 
+l'errore viene ritornato interrompendo il ciclo.
 
-Nel caso della lettura se il numero di bytes letti è zero significa che è
+Nel caso della lettura, se il numero di byte letti è zero, significa che si è
 arrivati alla fine del file e pertanto si ritorna senza aver concluso la
-lettura di tutti i bytes richiesti. 
+lettura di tutti i byte 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 \figref{fig:net_cli_code} è 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}[!htb]
+  \footnotesize
+  \begin{lstlisting}{}
+#include <sys/types.h>   /* predefined types */
+#include <unistd.h>      /* include unix standard library */
+#include <arpa/inet.h>   /* IP addresses conversion utilities */
+#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 (\file{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 routine 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 un'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
+\func{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 \file{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 ciclo 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 \figref{fig:net_serv_code}, il sorgente completo
+(\file{ElemDaytimeTCPServer.c}) è allegato insieme agli altri file nella
+directory \file{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 utilities */
+#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 ciclo
+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.
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: