\chapter{Socket}
\label{cha:socket}

Il \textit{socket} (traducibile liberamente come \textsl{manicotto}) è uno dei
principali meccanismi di comunicazione fra programmi utilizzato in ambito unix
(e non solo). Il socket costituisce in sostanza un canale di comunicazione fra
due processi su cui si possono leggere e scrivere dati. 

La creazione di un socket restituisce un file descriptor con un comportamento
analogo a quello di una pipe ma a differenza di questa e degli altri
meccanismi esaminati nel capitolo \ref{cha:ipc} i socket non sono limitati
alla comunicazione fra processi che girano sulla stessa macchina ma possono
effettuare la comunicazione anche attraverso la rete.

I socket infatti sono la principale API (\textit{Application Program
  Interface}) usata nella programmazione di rete. La loro origine risale al
1983, quando furono introdotti nel BSD 4.2; l'interfaccia è rimasta
sostanzialmente la stessa con piccole modifiche negli anni successivi. Benché
siano state sviluppate interfacce alternative, originate dai sistemi SYSV,
come la XTI (\textit{X/Open Transport Interface}) nessuna ha mai raggiunto la
diffusione e la popolarità di quella dei socket (né tantomeno usabilità e
flessibilità).

La flessibilità e la genericità dell'interfaccia inoltre ha consentito di
utilizzare i socket con i più disparati meccanismi di comunicazione, e non
solo con la suite dei protocolli TCP/IP, che sarà comunque quella di cui
tratteremo in maniera più estesa.


\section{Concetti base}
\label{sec:sock_gen}

Per capire il funzionamento dei socket occorre avere presente il funzionamento
dei protocolli di rete (vedi \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 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 dello ``stile'' di comunicazione
usato.  La scelta di questo stile va infatti ad incidere sulla semantica che
verrà utilizzata a livello utente per gestire la comunicazione (su come
inviare e ricevere i dati) e sul comportamento effettivo delle funzioni
utilizzate.

La scelta di uno stile dipende sia dai meccanismi disponibili, sia dal tipo di
comunicazione che si vuole effettuare. Ad esempio alcuni stili di
comunicazione considerano i dati come una sequenza continua di bytes, altri
invece li raggruppano in blocchi (i pacchetti).

Un'altro esempio di stile concerne la possibilità che la comunicazione possa o
meno perdere dati, possa o meno non rispettare l'ordine in cui essi non sono
inviati, o inviare dei pacchetti più volte (come nel caso di TCP e UDP).

Un terzo esempio di stile di comunicazione concerne le modalità in cui essa
avviene, in certi casi essa può essere condotta con una connessione diretta
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.

É chiaro che ciascuno di questi stili comporta una modalità diversa di gestire
la comunicazione, ad esempio se è inaffidabile occorrerà essere in grado di
gestire la perdita o il rimescolamento dei dati.

Dati i tanti e diversi protocolli di comunicazione disponibili, esistono vari
tipi di socket, che vengono classificati raggruppandoli in quelli che si
chiamano \textsl{domini} (\textit{domains}).  La scelta di un dominio equivale
in sostanza alla scelta di una famiglia di protocolli. Ciascun dominio ha un
suo nome simbolico che convenzionalmente inizia con \texttt{PF\_} (da
\textit{Protocol Family}, altro nome con cui si indicano i domini). 

A ciascun tipo di dominio corrisponde un analogo nome simbolico che inizia per
\texttt{AF\_} da \textit{Address Family}, nome che useremo anche noi; le man
pages di linux si riferiscono a questi anche come \textit{name space}, (nome
che però il manuale della glibc riserva ai domini) e che identifica il formato
degli indirizzi usati in quel dominio.

I domini (e i relativi nomi simbolici) sono definiti dall'header
\textit{socket.h}. In linux sono disponibili le famiglie di protocolli
riportate in \ntab.

\begin{table}[htb]
  \centering
  \begin{tabular}[c]{lll}
       Nome               & Utilizzo                       & Man page   \\
       PF\_UNIX,PF\_LOCAL & Local communication            & unix(7)    \\
       PF\_INET           & IPv4 Internet protocols        & ip(7)      \\
       PF\_INET6          & IPv6 Internet protocols        &            \\
       PF\_IPX            & IPX - Novell protocols         &            \\
       PF\_NETLINK        & Kernel user interface device   & netlink(7) \\
       PF\_X25            & ITU-T X.25 / ISO-8208 protocol & x25(7)     \\
       PF\_AX25           & Amateur radio AX.25 protocol   &            \\
       PF\_ATMPVC         & Access to raw ATM PVCs         &            \\
       PF\_APPLETALK      & Appletalk                      & ddp(7)     \\
       PF\_PACKET         & Low level packet interface     & packet(7)  \\    
  \end{tabular}
  \caption{Famiglie di protocolli definiti in linux}
  \label{tab:net_pf_names}
\end{table}

La scelta di un dominio non comporta però la scelta dello stile di
comunicazione, questo infatti viene a dipendere dal protocollo che si andrà ad
utilizzare fra quelli disponibili nella famiglia scelta. Le API permettono di
scegliere lo stile di comunicazione indicando il tipo di socket; linux e le
glibc mettono a disposizione i seguenti tipi di socket (che il manuale della
glibc chiama \textit{styles}) definiti come \texttt{int} in \texttt{socket.h}:

\begin{list}{}{}
\item \texttt{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
  byte (da cui il nome \textit{stream}). Vedi \ref{sec:sock_stream}.
\item \texttt{SOCK\_DGRAM} Viene usato per mandare pacchetti di lunghezza
  massima fissata (\textit{datagram}) indirizzati singolarmente, senza
  connessione e in maniera non affidabile. È l'opposto del precedente. Vedi
  \ref{sec:sock_dgram}.
\item \texttt{SOCK\_SEQPACKET} Provvede un canale di trasmissione di dati
  bidirezionale, sequenziale e affidabile. Opera su una connessione con un
  altro socket. I dati possono solo essere trasmessi e letti per pacchetti (di
  dimensione massima fissata).
\item \texttt{SOCK\_RAW} Provvede l'accesso a basso livello ai protocolli di
  rete e alle varie interfacce. I normali programmi di comunicazione non
  devono usarlo.
\item \texttt{SOCK\_RDM} Provvede un canale di trasmissione di pacchetti
  affidabile ma in cui non è garantito l'ordine di arrivo dei pacchetti.
\item \texttt{SOCK\_PACKET} Obsoleto, non deve essere usato.
\end{list}





