X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=socket.tex;h=ef729a56eb0e35ae88b95d02b57f4e7c911696f1;hp=82826224f27a79c33ff241d26fa787df4222c284;hb=65a5b6a82bdcfeefa6ebc270fe759f3a38560d33;hpb=0c9d95dfc21869e96f8a3e3ab8111c842e85a1f9 diff --git a/socket.tex b/socket.tex index 8282622..ef729a5 100644 --- a/socket.tex +++ b/socket.tex @@ -26,10 +26,11 @@ Il \textit{socket}\footnote{una traduzione letterale potrebbe essere sempre la parola inglese.} è uno dei principali meccanismi di comunicazione fra programmi utilizzato in ambito Unix. Il socket costituisce in sostanza un canale di comunicazione fra due processi su cui si possono leggere e scrivere -dati analogo a quello di una pipe ma a differenza di questa e degli altri -meccanismi esaminati nel capitolo \capref{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. +dati analogo a quello di una pipe (vedi \secref{sec:ipc_pipes}) ma a +differenza di questa e degli altri meccanismi esaminati nel capitolo +\capref{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. Quella dei socket costituisce infatti la principale API (\textit{Application Program Interface}) usata nella programmazione di rete. La loro origine @@ -37,8 +38,8 @@ risale al 1983, quando furono introdotti nel BSD 4.2; l'interfaccia sostanzialmente la stessa con piccole modifiche negli anni successivi. Benché siano state sviluppate interfacce alternative, originate dai sistemi SVr4, 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à). +diffusione e la popolarità di quella dei socket (né tantomeno la stessa +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 @@ -57,11 +58,11 @@ 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. +affrontare cambiano radicalmente a seconda dello \textsl{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 @@ -115,7 +116,7 @@ socket, per cui viene messo a zero (con l'eccezione dei \textit{raw socket}). Apre un socket. \bodydesc{La funzione restituisce un intero positivo se riesce, e -1 se - fallisce, in quest'ultimo caso la variabile \var{errno} è settata con i + fallisce, in quest'ultimo caso la variabile \var{errno} è impostata con i seguenti codici di errore: \begin{errlist} @@ -148,9 +149,10 @@ 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}, e che identifica il formato degli -indirizzi usati in quel dominio; 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. +indirizzi usati in quel dominio; le pagine di manuale di Linux si riferiscono +a questi anche come \textit{name space}, (nome che però il manuale delle +\acr{glibc} riserva ai domini) e che identifica il formato degli indirizzi +usati in quel dominio. L'idea alla base della distinzione era che una famiglia di protocolli potesse supportare vari tipi di indirizzi, per cui il prefisso \texttt{PF\_} si @@ -162,7 +164,7 @@ nomi sono equivalenti e corrispondono agli stessi valori. I domini (e i relativi nomi simbolici), così come i nomi delle famiglie di indirizzi sono definiti dall'header \textit{socket.h}. In Linux le famiglie di -protocolli disponibili sono riportate in \ntab. +protocolli disponibili sono riportate in \tabref{tab:net_pf_names}. \begin{table}[htb] \footnotesize @@ -175,7 +177,7 @@ protocolli disponibili sono riportate in \ntab. \macro{PF\_UNIX}, \macro{PF\_LOCAL} & Local communication & unix(7) \\ \macro{PF\_INET} & IPv4 Internet protocols & ip(7) \\ - \macro{PF\_INET6} & IPv6 Internet protocols & \\ + \macro{PF\_INET6} & IPv6 Internet protocols & ipv6(7) \\ \macro{PF\_IPX} & IPX - Novell protocols & \\ \macro{PF\_NETLINK}& Kernel user interface device & netlink(7) \\ \macro{PF\_X25} & ITU-T X.25 / ISO-8208 protocol & x25(7) \\ @@ -191,8 +193,8 @@ protocolli disponibili sono riportate in \ntab. Non tutte le famiglie di protocolli sono accessibili dall'utente generico, ad esempio in generale tutti i socket di tipo \macro{SOCK\_RAW} possono essere -creati solo da processi che hanno i privilegi di root (cioè effective uid -uguale a zero) o la capability \macro{CAP\_NET\_RAW}. +creati solo da processi che hanno i privilegi di root (cioè con userid +effettivo uguale a zero) o con la capability \macro{CAP\_NET\_RAW}. \subsection{Il tipo, o stile} @@ -202,8 +204,9 @@ La scelta di un dominio non comporta per 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 \ctyp{int} in \file{socket.h}: +\acr{glibc} mettono a disposizione i seguenti tipi di socket (che il manuale +della \acr{glibc} chiama \textit{styles}) definiti come \ctyp{int} in +\file{socket.h}: \begin{list}{}{} \item \macro{SOCK\_STREAM} Provvede un canale di trasmissione dati @@ -225,10 +228,10 @@ glibc chiama \textit{styles}) definiti come \ctyp{int} in \file{socket.h}: \item \macro{SOCK\_PACKET} Obsoleto, non deve essere usato. \end{list} -Si tenga presente che non tutte le combinazioni di famiglia di protocolli e -tipo di socket sono valide, in quanto non è detto che nella famiglia esista un -protocollo per tutti gli stili di comunicazione indicati qui sopra. Una -tabella che mostra le combinazioni valide è la seguente: +Si tenga presente che non tutte le combinazioni fra una famiglia di protocolli +e un tipo di socket sono valide, in quanto non è detto che in una famiglia +esista un protocollo per ciascuno dei diversi stili di comunicazione appena +elencati. \begin{table}[htb] \footnotesize @@ -266,9 +269,11 @@ tabella che mostra le combinazioni valide \label{tab:sock_sock_valid_combinations} \end{table} -Dove per ogni combinazione valida si è indicato il tipo di protocollo, o la -parola \textsl{si} qualora non il protocollo non abbia un nome definito, -mentre si sono lasciate vuote le caselle per le combinazioni non supportate. +In \secref{tab:sock_sock_valid_combinations} sono mostrate le combinazioni +valide possibili per le varie famiglie di protocolli. Per ogni combinazione +valida si è indicato il tipo di protocollo, o la parola \textsl{si} qualora +non il protocollo non abbia un nome definito, mentre si sono lasciate vuote le +caselle per le combinazioni non supportate. @@ -300,10 +305,10 @@ attraverso puntatori (cio maneggiare puntatori a strutture relative a tutti gli indirizzi possibili nelle varie famiglie di protocolli; questo pone il problema di come passare questi puntatori, il C ANSI risolve questo problema coi i puntatori generici -(i \ctyp{void *}), ma l'interfaccia dei socket è antecedente alla -definizione dello standard ANSI, e per questo nel 1982 fu scelto di definire -una struttura generica \type{sockaddr} per gli indirizzi dei socket mostrata -in \nfig: +(i \ctyp{void *}), ma l'interfaccia dei socket è antecedente alla definizione +dello standard ANSI, e per questo nel 1982 fu scelto di definire una struttura +generica per gli indirizzi dei socket, \type{sockaddr}, che si è riportata in +\figref{fig:sock_sa_gen_struct}. \begin{figure}[!htb] \footnotesize @@ -323,9 +328,9 @@ invocano dette funzioni passando l'indirizzo di un protocollo specifico occorrerà eseguire un casting del relativo puntatore. I tipi di dati che compongono la struttura sono stabiliti dallo standard -POSIX.1g, riassunti in \ntab\ con i rispettivi file di include in cui sono -definiti; la struttura è invece definita nell'include file -\file{sys/socket.h} +POSIX.1g, riassunti in \tabref{tab:sock_data_types} con i rispettivi file di +include in cui sono definiti; la struttura è invece definita nell'include file +\file{sys/socket.h}. \begin{table}[!htb] \centering @@ -354,7 +359,7 @@ definiti; la struttura \hline \end{tabular} \caption{Tipi di dati usati nelle strutture degli indirizzi, secondo quanto - stabilito dallo standard POSIX.1g} + stabilito dallo standard POSIX.1g.} \label{tab:sock_data_types} \end{table} @@ -379,8 +384,8 @@ l'uso di questa struttura. I socket di tipo \macro{PF\_INET} vengono usati per la comunicazione attraverso internet; la struttura per gli indirizzi per un socket internet (IPv4) è definita come \type{sockaddr\_in} nell'header file -\file{netinet/in.h} e secondo le man page ha la forma mostrata in \nfig, -conforme allo standard POSIX.1g. +\file{netinet/in.h} e secondo le pagine di manuale ha la forma mostrata in +\figref{fig:sock_sa_ipv4_struct}, conforme allo standard POSIX.1g. \begin{figure}[!htb] \footnotesize @@ -405,14 +410,14 @@ internet di un'interfaccia pi prevede numeri di porta, che sono utilizzati solo dai protocolli di livello superiore come TCP e UDP. Questa struttura però viene usata anche per i socket RAW che accedono direttamente al livello di IP, nel qual caso il numero della -porta viene settato al numero di protocollo. +porta viene impostato al numero di protocollo. -Il membro \var{sin\_family} deve essere sempre settato; \var{sin\_port} +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 (effective uid -uguale a zero) o con la capability \macro{CAP\_NET\_BIND\_SERVICE} possono -usare la funzione \func{bind} su queste porte. +servizi standard. Soltanto processi con i privilegi di root (con userid +effettivo uguale a zero) o con la capability \macro{CAP\_NET\_BIND\_SERVICE} +possono usare la funzione \func{bind} su queste porte. Il membro \var{sin\_addr} contiene l'indirizzo internet dell'altro capo della comunicazione, e viene acceduto sia come struttura (un resto di una @@ -455,7 +460,7 @@ struct in6_addr { \label{fig:sock_sa_ipv6_struct} \end{figure} -Il campo \var{sin6\_family} deve essere sempre settato ad +Il campo \var{sin6\_family} deve essere sempre impostato ad \macro{AF\_INET6}, il campo \var{sin6\_port} è analogo a quello di IPv4 e segue le stesse regole; il campo \var{sin6\_flowinfo} è a sua volta diviso in tre parti di cui i 24 bit inferiori indicano l'etichetta di flusso, i @@ -475,12 +480,13 @@ possibilit \subsection{La struttura degli indirizzi locali} \label{sec:sock_sa_local} -I socket di tipo \macro{PF\_UNIX} vengono usati per una comunicazione -efficiente fra processi che stanno sulla stessa macchina; essi rispetto ai +I socket di tipo \macro{PF\_UNIX} o \macro{PF\_LOCAL} vengono usati per una +comunicazione fra processi che stanno sulla stessa macchina (per vengono +chiamati \textit{local domain} o anche \textit{Unix domain}); essi rispetto ai precedenti possono essere anche creati in maniera anonima attraverso la -funzione \func{socketpair}. Quando però si vuole fare riferimento esplicito -ad uno di questi socket si deve usare la seguente struttura di indirizzi -definita nel file di header \file{sys/un.h}. +funzione \func{socketpair} (vedi \secref{sec:ipc_socketpair}). Quando però si +vuole fare riferimento esplicito ad uno di questi socket si deve usare la +seguente struttura di indirizzi definita nel file di header \file{sys/un.h}. \begin{figure}[!htb] \footnotesize @@ -676,7 +682,7 @@ e \textit{numeric}. 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} +indicata non è valida entrambe le funzioni impostano la variabile \var{errno} al valore \macro{EAFNOSUPPORT}. I prototipi delle suddette funzioni sono i seguenti: \begin{prototype}{sys/socket.h} @@ -698,7 +704,7 @@ seguenti: \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 + quest'ultimo caso viene impostata 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.} @@ -779,8 +785,9 @@ ssize_t SockRead(int fd, void *buf, size_t count) 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 +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] @@ -835,9 +842,10 @@ 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. +In \figref{fig:net_cli_code} è 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 @@ -957,7 +965,7 @@ necessario deve provvedere il programma stesso. 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 +nuovamente mostrato in \figref{fig:net_serv_code}, il sorgente completo (\file{ElemDaytimeTCPServer.c}) è allegato insieme agli altri file nella directory \file{sources}.