Fatte mq_open, mq_close, mq_unlink, mq_setattr, mq_getaddr.
[gapil.git] / socket.tex
index 54e7d48662850309a35c522406d298928c910023..2e34e78d3bdeaaa3bab7428c8740310ecc3b36ec 100644 (file)
@@ -27,6 +27,8 @@ concluderemo il capitolo con un primo esempio di applicazione.
 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.
+\index{socket|(}
+
 
 \subsection{I \textit{socket}}
 \label{sec:sock_socket_def}
@@ -88,8 +90,8 @@ avviene, in certi casi essa pu
 con un solo partner come per una telefonata; altri casi possono prevedere una
 comunicazione come per lettera, in cui si scrive l'indirizzo su ogni
 pacchetto, altri ancora una comunicazione \textit{broadcast} come per la
-radio, in cui i pacchetti vengono emessi su appositi ``canali'' dove chiunque
-si collega possa riceverli.
+radio, in cui i pacchetti vengono emessi su appositi ``\textsl{canali}'' dove
+chiunque si collega possa riceverli.
 
 É chiaro che ciascuno di questi stili comporta una modalità diversa di gestire
 la comunicazione, ad esempio se è inaffidabile occorrerà essere in grado di
@@ -108,10 +110,10 @@ il tipo di comunicazione che esso deve utilizzare.
 \label{sec:sock_socket}
 
 La creazione di un socket avviene attraverso l'uso della funzione
-\func{socket}; questa restituisce un \textit{file descriptor}\footnote{del
+\funcd{socket}; questa restituisce un \textit{file descriptor}\footnote{del
   tutto analogo a quelli che si ottengono per i file di dati e le pipe,
   descritti in \secref{sec:file_fd}.} che serve come riferimento al socket; il
-suo protototipo è:
+suo prototipo è:
 \begin{prototype}{sys/socket.h}{int socket(int domain, int type, int protocol)}
 
   Apre un socket.
@@ -202,7 +204,7 @@ protocolli disponibili sono riportate in \tabref{tab:net_pf_names}.
 
 Non tutte le famiglie di protocolli sono accessibili dall'utente generico, ad
 esempio in generale tutti i socket di tipo \const{SOCK\_RAW} possono essere
-creati solo da processi che hanno i privilegi di root (cioè con userid
+creati solo da processi che hanno i privilegi di root (cioè con user-ID
 effettivo uguale a zero) o con la capability \texttt{CAP\_NET\_RAW}.
 
 
@@ -316,7 +318,7 @@ 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 \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
+generica per gli indirizzi dei socket, \struct{sockaddr}, che si è riportata in
 \figref{fig:sock_sa_gen_struct}.
 
 \begin{figure}[!htb]
@@ -329,7 +331,8 @@ struct sockaddr {
 };
     \end{lstlisting}
   \end{minipage} 
-  \caption{La struttura generica degli indirizzi dei socket \type{sockaddr}}
+  \caption{La struttura generica degli indirizzi dei socket
+    \structd{sockaddr}.} 
   \label{fig:sock_sa_gen_struct}
 \end{figure}
 
@@ -376,7 +379,7 @@ include in cui sono definiti; la struttura 
 \end{table}
 
 In alcuni sistemi la struttura è leggermente diversa e prevede un primo membro
-aggiuntivo \var{uint8\_t sin\_len} (come riportato da R. Stevens nei suoi
+aggiuntivo \code{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 esiste. Il campo
 \type{sa\_family\_t} era storicamente un \ctyp{unsigned short}.
@@ -395,7 +398,7 @@ l'uso di questa struttura.
 
 I socket di tipo \const{PF\_INET} vengono usati per la comunicazione
 attraverso internet; la struttura per gli indirizzi per un socket internet
-(IPv4) è definita come \type{sockaddr\_in} nell'header file
+(IPv4) è definita come \struct{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.
 
@@ -415,7 +418,7 @@ struct in_addr {
     \end{lstlisting}
   \end{minipage} 
   \caption{La struttura degli indirizzi dei socket internet (IPv4)
-    \type{sockaddr\_in}.}
+    \structd{sockaddr\_in}.}
   \label{fig:sock_sa_ipv4_struct}
 \end{figure}
 
@@ -429,13 +432,13 @@ porta viene impostato al numero di protocollo.
 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 (con userid
+servizi standard. Soltanto processi con i privilegi di root (con user-ID
 effettivo uguale a zero) o con la capability \texttt{CAP\_NET\_BIND\_SERVICE}
 possono usare la funzione \func{bind} su queste porte.
 
 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 \texttt{union} usata per
+implementazione precedente in cui questa era una \direct{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
@@ -472,7 +475,7 @@ struct in6_addr {
     \end{lstlisting}
   \end{minipage} 
   \caption{La struttura degli indirizzi dei socket IPv6 
-    \type{sockaddr\_in6}.}
+    \structd{sockaddr\_in6}.}
   \label{fig:sock_sa_ipv6_struct}
 \end{figure}
 
@@ -488,7 +491,7 @@ 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 \var{sockaddr} generica,
+Si noti che questa struttura è più grande di una \struct{sockaddr} generica,
 quindi occorre stare attenti a non avere fatto assunzioni riguardo alla
 possibilità di contenere i dati nelle dimensioni di quest'ultima.
 
@@ -516,7 +519,7 @@ struct sockaddr_un {
     \end{lstlisting}
   \end{minipage} 
   \caption{La struttura degli indirizzi dei socket locali 
-    \var{sockaddr\_un}.}
+    \structd{sockaddr\_un}.}
   \label{fig:sock_sa_local_struct}
 \end{figure}
 
@@ -560,7 +563,7 @@ cosa significa tutto ci
 utile anche in seguito.
 
 
-\subsection{La \textit{endianess}}
+\subsection{La \textit{endianess}\index{endianess}}
 \label{sec:sock_endianess}
 
 La rappresentazione di un numero binario in un computer può essere fatta in
@@ -579,12 +582,12 @@ significativi nell'indirizzo successivo; questo ordinamento 
 numero. Il caso opposto, in cui si parte dal bit meno significativo è detto
 per lo stesso motivo \textit{big endian}.
 
-La \textit{endianess} di un computer dipende essenzialmente dalla architettura
-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}.
+La \textit{endianess}\index{endianess} di un computer dipende essenzialmente
+dalla architettura 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 PCI, 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
@@ -596,32 +599,34 @@ 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 byte in cui è
-suddiviso scambiati di posto, e ne sarà quindi invertito l'ordine di lettura
-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
-sul computer e quello che viene usato nelle trasmissione sulla rete; queste
-funzioni sono:
+Il problema connesso all'endianess\index{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 byte in cui è suddiviso scambiati di posto, e ne sarà quindi
+invertito l'ordine di lettura per cui, per riavere il valore originale
+dovranno essere rovesciati.
+
+Per questo motivo si usano delle funzioni di conversione che servono a tener
+conto automaticamente della possibile differenza fra l'ordinamento usato sul
+computer e quello che viene usato nelle trasmissione sulla rete; queste
+funzioni sono \funcd{htonl}, \funcd{htons}, \funcd{ntonl} e \funcd{ntons} ed i
+rispettivi prototipi sono:
 \begin{functions}
   \headdecl{netinet/in.h}
   \funcdecl{unsigned long int htonl(unsigned long int hostlong)} 
-  Converte l'intero a 32 bit \var{hostlong} dal formato della macchina a
+  Converte l'intero a 32 bit \param{hostlong} dal formato della macchina a
   quello della rete.
  
   \funcdecl{unsigned short int htons(unsigned short int hostshort)}
-  Converte l'intero a 16 bit \var{hostshort} dal formato della macchina a
+  Converte l'intero a 16 bit \param{hostshort} dal formato della macchina a
   quello della rete.
 
   \funcdecl{unsigned long int ntonl(unsigned long int netlong)}
-  Converte l'intero a 32 bit \var{netlong} dal formato della rete a quello
+  Converte l'intero a 32 bit \param{netlong} dal formato della rete a quello
   della macchina.
 
   \funcdecl{unsigned sort int ntons(unsigned short int netshort)}
-  Converte l'intero a 16 bit \var{netshort} dal formato della rete a quello
+  Converte l'intero a 16 bit \param{netshort} dal formato della rete a quello
   della macchina.
   
   \bodydesc{Tutte le funzioni restituiscono il valore convertito, e non hanno
@@ -647,38 +652,54 @@ assicurare la portabilit
 \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 normalmente.
+binario usato nelle strutture degli indirizzi alla rappresentazione simbolica
+dei numeri 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 \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 \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 \val{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
-  \const{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 \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}
+mnemonico per indicare la stringa. Dette funzioni sono \funcd{inet\_addr},
+\funcd{inet\_aton} e \funcd{inet\_ntoa}, ed i rispettivi prototipi sono:
+\begin{functions}
+  \headdecl{arpa/inet.h}
+  
+  \funcdecl{in\_addr\_t inet\_addr(const char *strptr)} Converte la stringa
+  dell'indirizzo \textit{dotted decimal} in nel numero IP in network order.
+
+  \funcdecl{int inet\_aton(const char *src, struct in\_addr *dest)} Converte
+  la stringa dell'indirizzo \textit{dotted decimal} in un indirizzo IP.
+
+  \funcdecl{char *inet\_ntoa(struct in\_addr addrptr)}
+  Converte un indirizzo IP in una stringa \textit{dotted decimal}.
+
+  \bodydesc{Tutte queste le funzioni non generano codice di errore.}
+\end{functions}
+
+La prima funzione, \func{inet\_addr}, restituisce l'indirizzo a 32 bit in
+network order (del tipo \type{in\_addr\_t}) a partire dalla stringa passata
+nell'argomento \param{strptr}. In caso di errore (quando la stringa non esprime
+un indirizzo valido) restituisce invece il valore \const{INADDR\_NONE} che
+tipicamente sono trentadue bit a uno.  Questo però 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
+di \func{inet\_aton}.
+
+La funzione \func{inet\_aton} converte la stringa puntata da \param{src}
+nell'indirizzo binario che viene memorizzato nell'opportuna struttura
+\struct{in\_addr} (si veda \secref{fig:sock_sa_ipv4_struct}) situata
+all'indirizzo dato dall'argomento \param{dest} (è espressa in questa forma in
+modo da poterla usare direttamente con il puntatore usato per passare la
+struttura degli indirizzi). La funzione restituisce 0 in caso di successo e 1
+in caso di fallimento.  Se usata con \param{dest} inizializzato a \val{NULL}
+effettua la validazione dell'indirizzo.
+
+L'ultima funzione, \func{inet\_ntoa}, 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.
 
 
 \subsection{Le funzioni \func{inet\_pton} e \func{inet\_ntop}}
@@ -701,54 +722,62 @@ e \textit{numeric}.
 % \end{figure}
 
 Entrambe le funzioni accettano l'argomento \param{af} che indica il tipo di
-indirizzo e può essere soltanto \const{AF\_INET} o \const{AF\_INET6}. I
-prototipi delle suddette funzioni sono i seguenti:
+indirizzo e può essere soltanto \const{AF\_INET} o \const{AF\_INET6}. La prima
+funzione è \funcd{inet\_pton}, che serve a convertire una stringa in un
+indirizzo, il suo prototipo è:
 \begin{prototype}{sys/socket.h}
 {int inet\_pton(int af, const char *src, void *addr\_ptr)} 
 
   Converte l'indirizzo espresso tramite una stringa nel valore numerico.
   
-  \bodydesc{La funzione restituisce un valore negativo se \var{af} specifica
-    una famiglia di indirizzi non valida, settando \var{errno} a
+  \bodydesc{La funzione restituisce un valore negativo se \param{af} specifica
+    una famiglia di indirizzi non valida, con \var{errno} che assume il valore
     \errcode{EAFNOSUPPORT}, un valore nullo se \param{src} non rappresenta un
     indirizzo valido, ed un valore positivo in caso di successo.}
 \end{prototype}
 
 La funzione converte la stringa indicata tramite \param{src} nel valore
 numerico dell'indirizzo IP del tipo specificato da \param{af} che viene
-memorizzato all'indirizzo puntato da \var{addr\_ptr}, la funzione restituisce
+memorizzato all'indirizzo puntato da \param{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
+un indirizzo valido, e negativo se \param{af} specifica una famiglia di
 indirizzi non valida.
 
-
+La seconda funzione è \funcd{inet\_ntop} che converte un indirizzo in una
+stringa; il suo prototipo è:
 \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
-  \const{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e
-  \const{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve
-  comunque venire specificata attraverso il parametro \var{len}.
+  Converte l'indirizzo dalla relativa struttura in una stringa simbolica.
  
-  \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
-    \errval{ENOSPC} in caso le dimensioni dell'indirizzo eccedano la lunghezza
-    specificata da \var{len} o \errval{ENOAFSUPPORT} in caso \var{af} non sia
-    una famiglia di indirizzi valida.}
+  \bodydesc{La funzione restituisce un puntatore non nullo alla stringa
+    convertita in caso di successo e \val{NULL} in caso di fallimento, nel
+    qual caso \var{errno} assume i valori: 
+    \begin{errlist}
+    \item[\errcode{ENOSPC}] le dimensioni della stringa con la conversione
+      dell'indirizzo eccedono la lunghezza specificata da \param{len}.
+    \item[\errcode{ENOAFSUPPORT}] la famiglia di indirizzi \param{af} non è
+      una valida.
+  \end{errlist}}
 \end{prototype}
 
+La funzione converte la struttura dell'indirizzo puntata da \param{addr\_ptr}
+in una stringa che viene copiata nel buffer puntato dall'indirizzo
+\param{dest}; questo deve essere preallocato dall'utente e la lunghezza deve
+essere almeno \const{INET\_ADDRSTRLEN} in caso di indirizzi IPv4 e
+\const{INET6\_ADDRSTRLEN} per indirizzi IPv6; la lunghezza del buffer deve
+comunque venire specificata attraverso il parametro \param{len}.
+
 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.
+(una struttura \struct{in\_addr} per IPv4, e una struttura \struct{in6\_addr}
+per IPv6), che devono essere precedentemente allocate e passate attraverso il
+puntatore \param{addr\_ptr}; l'argomento \param{dest} di \func{inet\_ntop} non
+può essere nullo e deve essere allocato precedentemente.
 
 Il formato usato per gli indirizzi in formato di presentazione è la notazione
-\textit{dotted decimal} per IPv4 e quella descritta in
+\textit{dotted decimal} per IPv4 e quello descritto in
 \secref{sec:IP_ipv6_notation} per IPv6.
 
+\index{socket|)}
 
 
 \section{Un esempio di applicazione}
@@ -756,8 +785,9 @@ Il formato usato per gli indirizzi in formato di presentazione 
 
 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.
+passare agli esempi del client e del server, ritorniamo con maggiori dettagli
+su una caratteristica delle funzioni di I/O che nel caso dei socket è
+particolarmente rilevante, e che ci tornerà utile anche in seguito.
 
 
 \subsection{Il comportamento delle funzioni di I/O}
@@ -771,13 +801,15 @@ per i socket di tipo stream).
 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.
+comportamento normale per l'I/O su file; con i normali file di dati il
+problema si avverte solo quando si incontra la fine del file, ma in generale
+non è così.
 
 In questo caso tutto quello che il programma chiamante deve fare è di ripetere
-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).
+la lettura (o scrittura) per la quantità di byte rimanenti (e le funzioni si
+possono bloccare se i dati non sono disponibili): è lo stesso comportamento
+che si può avere scrivendo più di \const{PIPE\_BUF} byte in una pipe (si
+riveda quanto detto in \secref{sec:ipc_pipes}).
 
 \begin{figure}[htb]
   \centering
@@ -785,7 +817,7 @@ di solito adottato per il buffer di trasmissione del kernel).
   \begin{lstlisting}{}
 #include <unistd.h>
 
-ssize_t SockRead(int fd, void *buf, size_t count) 
+ssize_t FullRead(int fd, void *buf, size_t count) 
 {
     size_t nleft;
     ssize_t nread;
@@ -807,17 +839,17 @@ ssize_t SockRead(int fd, void *buf, size_t count)
     return (count - nleft);
 }  
   \end{lstlisting}
-  \caption{Funzione \func{SockRead}, legge \var{count} byte da un socket }
-  \label{fig:sock_SockRead_code}
+  \caption{Funzione \func{FullRead}, legge \var{count} byte da un socket }
+  \label{fig:sock_FullRead_code}
 \end{figure}
 
-Per questo motivo seguendo l'esempio di W. R. Stevens si sono definite due
-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 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}.
+Per questo motivo, seguendo l'esempio di W. R. Stevens in \cite{UNP1}, si sono
+definite due funzioni \func{FullRead} e \func{FullWrite} 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 byte
+specificato; il sorgente è riportato in \figref{fig:sock_FullRead_code} e
+\figref{fig:sock_FullWrite_code} ed è disponibile fra i sorgenti allegati alla
+guida nei files \file{FullRead.c} e \file{FullWrite.c}.
 
 \begin{figure}[htb]
   \centering
@@ -825,7 +857,7 @@ guida nei files \file{SockRead.c} e \file{SockWrite.c}.
   \begin{lstlisting}{}
 #include <unistd.h>
 
-ssize_t SockWrite(int fd, const void *buf, size_t count) 
+ssize_t FullWrite(int fd, const void *buf, size_t count) 
 {
     size_t nleft;
     ssize_t nwritten;
@@ -845,8 +877,8 @@ ssize_t SockWrite(int fd, const void *buf, size_t count)
     return (count);
 }  
   \end{lstlisting}
-  \caption{Funzione \func{SockWrite}, scrive \var{count} byte su un socket }
-  \label{fig:sock_SockWrite_code}
+  \caption{Funzione \func{FullWrite}, scrive \var{count} byte su un socket.}
+  \label{fig:sock_FullWrite_code}
 \end{figure}
 
 Come si può notare le funzioni ripetono la lettura/scrittura in un ciclo fino
@@ -856,8 +888,9 @@ dovuta ad un segnale), nel qual caso l'accesso viene ripetuto, altrimenti
 l'errore viene ritornato interrompendo il ciclo.
 
 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 byte richiesti.
+arrivati alla fine del file (per i socket questo significa in genere che
+l'altro capo è stato chiuso, e non è quindi più possibile leggere niente) e
+pertanto si ritorna senza aver concluso la lettura di tutti i byte richiesti.
 
 
 
@@ -945,12 +978,12 @@ comando (effettuata con le apposite routine illustrate in
 
 Il primo passo (\texttt{\small 14--18}) è creare un \textit{socket} IPv4
 (\const{AF\_INET}), di tipo TCP \const{SOCK\_STREAM}. La funzione
-\const{socket} ritorna il descrittore che viene usato per identificare il
+\func{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
+struttura \struct{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
@@ -1068,7 +1101,7 @@ 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
+come pure l'inizializzazione della struttura \struct{sockaddr\_in}, anche in
 questo caso si usa la porta standard del servizio daytime, ma come indirizzo
 IP si il valore predefinito \const{INET\_ANY} che corrisponde ad un indirizzo
 generico (\texttt{\small 27--31}).
@@ -1107,6 +1140,8 @@ come demone di sistema (che 
 attiva e il terminale da cui lo si è lanciato è stato sconnesso),
 occorrerebbero delle opportune modifiche.
 
+
+
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"