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
\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.
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}.
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.
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:
+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)}
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:
+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}
\bodydesc{Tutte queste le funzioni non generano codice di errore.}
\end{functions}
-La prima funcione, \func{inet\_addr}, restituisce l'indirizzo a 32 bit in
+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
-nellargomento \param{strptr}. In caso di errore (quando la stringa non esprime
+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
\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 restituesce 0 in caso di successo e 1
+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.
% \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)}
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 l'indirizzo dalla relativa struttura in una stringa simbolica.
\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 valor:
+ 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}.
\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;
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 in \cite{UNP1}, si sono
-definite due funzioni \func{SockRead} e \func{SockWrite} che eseguono la
+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_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}.
+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
\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;
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