+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 \func{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 \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
+ \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 \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 \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 \func{inet\_pton} e
+\func{inet\_ntop} che possono convertire anche gli indirizzi IPv6. Anche in
+questo caso le lettere \func{n} e \func{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 settano 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 settata 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}
+
+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.
+
+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.
+
+
+
+\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.
+
+
+\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
+socket è che le funzioni di input/output non sempre hanno lo stesso
+comportamento che avrebbero con i normali files (in particolare questo accade
+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.
+
+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).
+
+\begin{figure}[htb]
+ \centering
+ \footnotesize
+ \begin{lstlisting}{}
+#include <unistd.h>
+
+ssize_t SockRead(int fd, void *buf, size_t count)
+{
+ size_t nleft;
+ ssize_t nread;
+
+ nleft = count;
+ while (nleft > 0) { /* repeat until no left */
+ if ( (nread = read(fd, buf, nleft)) < 0) {
+ if (errno == EINTR) { /* if interrupted by system call */
+ continue; /* repeat the loop */
+ } else {
+ return(nread); /* otherwise exit */
+ }
+ } else if (nread == 0) { /* EOF */
+ break; /* break loop here */
+ }
+ nleft -= nread; /* set left to read */
+ buf +=nread; /* set pointer */
+ }
+ return (count - nleft);
+}
+ \end{lstlisting}
+ \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 \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 \curfig\ e \nfig\ ed è disponibile fra i sorgenti allegati alla
+guida nei files \file{SockRead.c} e \file{SockWrite.c}.
+
+\begin{figure}[htb]
+ \centering
+ \footnotesize
+ \begin{lstlisting}{}
+#include <unistd.h>
+
+ssize_t SockWrite(int fd, const void *buf, size_t count)
+{
+ size_t nleft;
+ ssize_t nwritten;
+
+ nleft = count;
+ while (nleft > 0) { /* repeat until no left */
+ if ( (nwritten = write(fd, buf, nleft)) < 0) {
+ if (errno == EINTR) { /* if interrupted by system call */
+ continue; /* repeat the loop */
+ } else {
+ return(nwritten); /* otherwise exit with error */
+ }
+ }
+ nleft -= nwritten; /* set left to write */
+ buf +=nwritten; /* set pointer */
+ }
+ return (count);
+}
+ \end{lstlisting}
+ \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 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 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.
+
+
+
+\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}[!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 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
+\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 \nfig, 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}