-memorizzato 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.
-
-
-\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}.
-
- \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.}
-\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 \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
- \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 è \errcode{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}