%% License".
%%
-\chapter{Introduzione ai socket}
+\chapter{I socket}
\label{cha:socket_intro}
In questo capitolo inizieremo a spiegare le caratteristiche salienti della
si utilizzerà per la comunicazione. Per evitare un'introduzione puramente
teorica concluderemo il capitolo con un primo esempio di applicazione.
-\section{Una panoramica}
+\section{Introduzione ai socket}
\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.
+In questa sezione daremo 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; ne illustreremo poi le caratteristiche e le differenti
+tipologie presenti ed infine tratteremo le modalità con cui possono essere
+creati.
\index{socket!definizione|(}
-\subsection{I \textit{socket}}
+\subsection{Cosa sono \textit{socket}}
\label{sec:sock_socket_def}
I \textit{socket} (una traduzione letterale potrebbe essere \textsl{presa}, ma
solo con l'insieme dei protocolli TCP/IP, anche se questa sarà comunque quella
di cui tratteremo in maniera più estesa.
-
-\subsection{Concetti base}
-\label{sec:sock_gen}
-
Per capire il funzionamento dei socket occorre avere presente il funzionamento
-dei protocolli di rete che su utilizzeranno (vedi cap.~\ref{cha:network}), ma
-l'interfaccia è del tutto generale e benché le problematiche, e quindi le
-modalità di risolvere i problemi, siano diverse a seconda del tipo di
-protocollo di comunicazione usato, le funzioni da usare nella gestione dei
-socket restano le stesse.
+dei protocolli di rete che su utilizzeranno (ed in particolare quelli del
+TCP/IP già illustrati in sez.~\ref{sec:net_tpcip}), ma l'interfaccia è del
+tutto generale e benché le problematiche, e quindi le modalità di risolvere i
+problemi, siano diverse a seconda del tipo di protocollo di comunicazione
+usato, le funzioni da usare nella gestione dei socket 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 del tipo di comunicazione usato.
-La scelta di questo tipo (sovente anche detto \textsl{stile}) va infatti ad
-incidere sulla semantica che verrà utilizzata a livello utente per gestire la
-comunicazione cioè su come inviare e ricevere i dati e sul comportamento
-effettivo delle funzioni utilizzate.
+La scelta di questo tipo di comunicazione (sovente anche detto \textsl{stile})
+va infatti ad incidere sulla semantica che verrà utilizzata a livello utente
+per gestire la comunicazione cioè su come inviare e ricevere i dati e sul
+comportamento effettivo delle funzioni utilizzate.
La scelta di uno \textsl{stile} dipende sia dai meccanismi disponibili, sia
dal tipo di comunicazione che si vuole effettuare. Ad esempio alcuni tipi di
essere condotta con una connessione diretta con un solo corrispondente, 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 \itindex{broadcast} \textit{broadcast} come per la radio, in cui
-i pacchetti vengono emessi su appositi ``\textsl{canali}'' dove chiunque si
-collega possa riceverli.
+comunicazione uno a molti come il \textit{broadcast} ed il \textit{multicast},
+in cui i pacchetti possono venire emessi su appositi ``\textsl{canali}'' dove
+chiunque si collega possa riceverli.
+
+É chiaro che ciascuno di questi diversi aspetti è associato ad un tipo di
+comunicazione che comporta una modalità diversa di gestire la stessa, ad
+esempio se la comunicazione è inaffidabile occorrerà essere in grado di
+gestire la perdita o il rimescolamento dei dati, se è a pacchetti questi
+dovranno essere opportunamente trattati, se è uno a molti occorrerà tener
+conto della eventuale unidirezionalità della stessa, ecc.
-É chiaro che ciascuno di questi diversi aspetti associato ad un tipo di
-comunicazione comporta una modalità diversa di gestire la stessa, ad esempio
-se è inaffidabile occorrerà essere in grado di gestire la perdita o il
-rimescolamento dei dati, se è a pacchetti questi dovranno essere
-opportunamente trattati, ecc.
+\index{socket!definizione|)}
-\section{La creazione di un socket}
+\subsection{La creazione di un socket}
\label{sec:sock_creation}
Come accennato l'interfaccia dei socket è estremamente flessibile e permette
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 di sistema
\funcd{socket}; essa restituisce un \textit{file descriptor} (del tutto
analogo a quelli che si ottengono per i file di dati e le \textit{pipe},
tre tipi, Linux supporta anche gli altri, come si può verificare nel file
\texttt{include/linux/net.h} dei sorgenti del kernel.}
-\begin{basedescript}{\desclabelwidth{2.9cm}\desclabelstyle{\nextlinelabel}}
+\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
\item[\const{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
devono usarlo, è riservato all'uso di sistema.
\item[\const{SOCK\_RDM}] Provvede un canale di trasmissione di dati
affidabile, ma in cui non è garantito l'ordine di arrivo dei pacchetti.
-\item[\const{SOCK\_PACKET}] Obsoleto, non deve essere più usato.\footnote{e
- pertanto non ne parleremo ulteriormente.}
+\item[\const{SOCK\_PACKET}] Obsoleto, non deve essere più usato (e pertanto
+ non ne parleremo ulteriormente).
\end{basedescript}
A partire dal kernel 2.6.27 l'argomento \param{type} della funzione
non strettamente attinenti all'indicazione del tipo secondo i valori appena
illustrati. Essi infatti possono essere combinati con un OR aritmetico delle
ulteriori costanti:
-\begin{basedescript}{\desclabelwidth{2.9cm}\desclabelstyle{\nextlinelabel}}
+\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
\item[\const{SOCK\_CLOEXEC}] imposta il flag di \textit{close-on-exec} sul
file descriptor del socket, ottenendo lo stesso effetto del flag
\const{O\_CLOEXEC} di \func{open} (vedi tab.~\ref{tab:open_operation_flag}),
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{\textwidth}
+ \begin{minipage}[c]{0.80\textwidth}
\includestruct{listati/sockaddr.h}
\end{minipage}
\caption{La struttura generica degli indirizzi dei socket
\begin{figure}[!htb]
\footnotesize\centering
- \begin{minipage}[c]{\textwidth}
+ \begin{minipage}[c]{0.80\textwidth}
\includestruct{listati/sockaddr_in.h}
\end{minipage}
\caption{La struttura \structd{sockaddr\_in} degli indirizzi dei socket
Il membro \var{sin\_addr} contiene un indirizzo internet, e viene acceduto sia
come struttura (un resto di una implementazione precedente in cui questa era
-una \direct{union} usata per accedere alle diverse classi di indirizzi) che
+una \dirct{union} usata per accedere alle diverse classi di indirizzi) che
direttamente come intero. In \headfile{netinet/in.h} vengono definite anche
alcune costanti che identificano alcuni indirizzi speciali, riportati in
tab.~\ref{tab:TCP_ipv4_addr}, che rincontreremo più avanti.
Infine occorre sottolineare che sia gli indirizzi che i numeri di porta devono
essere specificati in quello che viene chiamato \textit{network order}, cioè
con i bit ordinati in formato \textit{big endian} (vedi
-sez.~\ref{sec:sock_endianness}), questo comporta la necessità di usare apposite
+sez.~\ref{sec:endianness}), questo comporta la necessità di usare apposite
funzioni di conversione per mantenere la portabilità del codice (vedi
sez.~\ref{sec:sock_addr_func} per i dettagli del problema e le relative
soluzioni).
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{\textwidth}
+ \begin{minipage}[c]{0.80\textwidth}
\includestruct{listati/sockaddr_in6.h}
\end{minipage}
\caption{La struttura \structd{sockaddr\_in6} degli indirizzi dei socket
Il campo \var{sin6\_addr} contiene l'indirizzo a 128 bit usato da IPv6,
espresso da un vettore di 16 byte. Infine il campo \var{sin6\_scope\_id} è un
campo introdotto in Linux con il kernel 2.4, per gestire alcune operazioni
-riguardanti il \itindex{multicast} \textit{multicasting}. Si noti infine che
+riguardanti il \textit{multicasting}. Si noti infine che
\struct{sockaddr\_in6} ha una dimensione maggiore della struttura
\struct{sockaddr} generica di fig.~\ref{fig:sock_sa_gen_struct}, quindi
occorre stare attenti a non avere fatto assunzioni riguardo alla possibilità
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{\textwidth}
+ \begin{minipage}[c]{0.80\textwidth}
\includestruct{listati/sockaddr_un.h}
\end{minipage}
\caption{La struttura \structd{sockaddr\_un} degli indirizzi dei socket
\begin{figure}[!htb]
\footnotesize \centering
- \begin{minipage}[c]{\textwidth}
+ \begin{minipage}[c]{0.80\textwidth}
\includestruct{listati/sockaddr_atalk.h}
\end{minipage}
\caption{La struttura \structd{sockaddr\_atalk} degli indirizzi dei socket
usati solo da processi con i privilegi di amministratore o con la
\textit{capability} \const{CAP\_NET\_BIND\_SERVICE}. L'indirizzo remoto è
specificato nella struttura \var{sat\_addr}, e deve essere in \textit{network
- order} (vedi sez.~\ref{sec:sock_endianness}); esso è composto da un parte di
+ order} (vedi sez.~\ref{sec:endianness}); esso è composto da un parte di
rete data dal campo \var{s\_net}, che può assumere il valore
\const{AT\_ANYNET}, che indica una rete generica e vale anche per indicare la
rete su cui si è, il singolo nodo è indicato da \var{s\_node}, e può prendere
senso solo in questo caso. In particolare \var{sll\_pkttype} può assumere i
seguenti valori: \const{PACKET\_HOST} per un pacchetto indirizzato alla
macchina ricevente, \const{PACKET\_BROADCAST} per un pacchetto di
-\itindex{broadcast} \textit{broadcast}, \const{PACKET\_MULTICAST} per un
-pacchetto inviato ad un indirizzo fisico di \itindex{multicast}
-\textit{multicast}, \const{PACKET\_OTHERHOST} per un pacchetto inviato ad
-un'altra stazione (e ricevuto su un'interfaccia in \index{modo~promiscuo} modo
-promiscuo), \const{PACKET\_OUTGOING} per un pacchetto originato dalla propria
-macchina che torna indietro sul socket.
+\textit{broadcast}, \const{PACKET\_MULTICAST} per un pacchetto inviato ad un
+indirizzo fisico di \textit{multicast}, \const{PACKET\_OTHERHOST} per un
+pacchetto inviato ad un'altra stazione (e ricevuto su un'interfaccia in
+\index{modo~promiscuo} modo promiscuo), \const{PACKET\_OUTGOING} per un
+pacchetto originato dalla propria macchina che torna indietro sul socket.
Si tenga presente infine che in fase di ricezione, anche se si richiede il
\subsection{Le funzioni per il riordinamento}
\label{sec:sock_func_ord}
-Come già visto in sez.~\ref{sec:sock_endianness} il problema connesso
-\itindex{endianness} all'\textit{endianness} è 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. 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{ntohl} e \funcd{ntohs} ed i rispettivi prototipi sono:
+Come già visto in sez.~\ref{sec:endianness} il problema connesso
+all'\textit{endianness} è 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. 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{ntohl} e \funcd{ntohs} ed i rispettivi prototipi sono:
\begin{functions}
\headdecl{netinet/in.h}
\funcdecl{unsigned long int htonl(unsigned long int hostlong)}
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 è \index{funzioni!rientranti} rientrante.
+funzione non è rientrante.
\subsection{Le funzioni \func{inet\_pton} e \func{inet\_ntop}}
\textit{dotted decimal} per IPv4 e quello descritto in
sez.~\ref{sec:IP_ipv6_notation} per IPv6.
-\index{socket!definizione|)}
-