From e0531effd7737948e99e1a8146c3b5fb45590103 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Thu, 12 Apr 2001 21:00:03 +0000 Subject: [PATCH] Sistemato inizio capitolo sui socket --- network.tex | 41 +++----------- socket.tex | 156 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 150 insertions(+), 47 deletions(-) diff --git a/network.tex b/network.tex index 18d4ef6..473d0eb 100644 --- a/network.tex +++ b/network.tex @@ -53,11 +53,18 @@ viene terminato, mentre il server originale resta sempre attivo. \label{sec:net_cli_sample} Per evitare di rendere l'esposizione dei concetti generali sulla rete -puramente teorica iniziamo con il mostrare un semplice esempio di client TCP. +puramente teorica iniziamo con il mostrare un esempio di un client TCP +elementare. Scopo di questo esempio è fornire un primo approccio alla +programmazione di rete, tutto questo sarà esaminato in dettaglio nei capitoli +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 richesta. + \begin{figure}[!htbp] \footnotesize \begin{lstlisting}{} @@ -114,12 +121,6 @@ int main(int argc, char *argv[]) \label{fig:net_cli_code} \end{figure} -Scopo di questo esempio è fornire un primo approccio alla programmazione di -rete, per questo motivo non ci dilungheremo nello spiegare il significato dei -termini o il funzionamento delle varie funzioni utilizzate. Tutto questo sarà -esaminato in dettaglio nel seguito, per cui qui ci limiteremo a citarli senza -ulteriori dettagli. - Il sorgente completo del programma (\texttt{SimpleDaytimeTCPClient.c}, che comprende il trattamento delle opzioni e una funzione per stampare un messaggio di aiuto) è allegato alla guida nella sezione dei codici sorgente e @@ -746,29 +747,3 @@ stesso tempo, il che poi comporta che quanto dicevamo a proposito del controllo di flusso e della gestione della sequenzialità dei dati viene effettuato per entrambe le direzioni di comunicazione. - - - - -\chapter{Socket TCP elementari} - -Esamineremo in questo capitolo quanto necessario per capire come scrivere un -client e un server TCP, riprendendo quanto visto in \ref{sec:net_cli_sample} e -\ref{sec:net_cli_server}. - - - -\subsection{Creazione e terminazione della connessione TCP} - -Per capire il funzionamento delle funzioni della interfaccia dei socket che -operano con TCP (le varie \texttt{connect}, \texttt{accept}, \texttt{close} -che abbiamo visto negli esempi iniziali e su cui torneremo più avatni) è -fodamentale capire come funziona la creazione e la conclusione di una -connessione TCP. - - - - -\subsection{Le porte} - - diff --git a/socket.tex b/socket.tex index de622fc..076793f 100644 --- a/socket.tex +++ b/socket.tex @@ -4,13 +4,11 @@ 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. +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 +\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. Quella dei socket costituisce infatti la principale API (\textit{Application Program Interface}) usata nella programmazione di rete. La loro origine @@ -65,6 +63,53 @@ si collega possa riceverli. la comunicazione, ad esempio se è inaffidabile occorrerà essere in grado di gestire la perdita o il rimescolamento dei dati. + +\section{La funzione \texttt{socket}} +\label{sec:sock_socket} + +La creazione di un socket avviene attraverso l'uso della funzione +\texttt{socket} questa restituisce un \textit{socket descriptor} (un valore +intero non negativo) che come gli analoghi file descriptor di files e alle +pipes serve come riferimento al socket; in sostanza è l'indice nella tabella +dei file che contiene i puntatori alle opportune strutture usate dal kernel ed +allocate per ogni processo, (la stessa usata per i files e le pipes [NdA +verificare!]). + +Il prototipo della funzione è definito nell'header \texttt{sys/socket.h}, la +funzione prende tre parametri, il dominio del socket (che definisce la +famiglia di protocolli, vedi \ref{sec:sock_domain}), il tipo di socket (che +definisce lo stile di comunicazione vedi \ref{sec:sock_type}) e il protocollo; +in genere quest'ultimo è indicato implicitamente dal tipo di socket, per cui +viene messo a zero (con l'eccezione dei \textit{raw socket}). + +\begin{itemize} +\item \texttt{int socket(int domain, int type, int protocol)} + + La funzione restituisce un intero positivo se riesce, e -1 se fallisce, in + quest'ultimo caso la variabile \texttt{errno} è settata con i seguenti + codici di errore: + + \begin{itemize} + \item \texttt{EPROTONOSUPPORT} Il tipo di socket o il protocollo scelto non + sono supportati nel dominio. + \item \texttt{ENFILE} Il kernel non ha memoria sufficiente a creare una + nuova strutture per il socket. + \item \texttt{EMFILE} Si è ecceduta la tabella dei file. + \item \texttt{EACCES} Non si hanno privilegi per creare un socket nel + dominio o con il protocollo specificato. + \item \texttt{EINVAL} Protocollo sconosciuto o dominio non disponibile. + \item \texttt{ENOBUFS} o \texttt{ENOMEM} Non c'è sufficiente memoria per + creare il socket. + \end{itemize} +\end{itemize} + +Si noti che la creazione del socket non comporta nulla riguardo +all'indicazione degli indirizzi remoti o locali attraverso i quali si vuole +effettuare la comunicazione. + +\subsection{Il dominio, o \textit{protocol family}} +\label{sec:sock_domain} + 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 @@ -73,17 +118,25 @@ 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. +\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. +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 +sarebbe dovuto usare nella creazione dei socket e il prefisso \texttt{AF\_} in +quello delle strutture degli indirizzi; questo è quanto specificato anche +dallo standard POSIX1g, ma non esistono a tuttora famiglie di protocolli che +supportino diverse strutture di indirizzi, per cui nella pratica questi due +nomi sono equivalenti e corrispondono agli stessi valori. -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. +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. \begin{table}[htb] + \footnotesize \centering \begin{tabular}[c]{lll} Nome & Utilizzo & Man page \\ @@ -102,6 +155,14 @@ riportate in \ntab. \label{tab:net_pf_names} \end{table} +Non tutte le famiglie di protocolli sono accessibili dall'utente generico, +come forma di protezione infatti soltanto root può usare i protocolli di basso +livello [NdA approfondire]. + + +\subsection{Il tipo, o stile} +\label{sec:sock_type} + 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 @@ -131,3 +192,70 @@ glibc chiama \textit{styles}) definiti come \texttt{int} in \texttt{socket.h}: \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 combianazioni valide è la seguente: + +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}{l|c|c|c|c|c|} + &\multicolumn{1}{c}{\texttt{SOCK\_STREAM}}& + \multicolumn{1}{c}{\texttt{SOCK\_DGRAM}} & + \multicolumn{1}{c}{\texttt{SOCK\_RAW}} & + \multicolumn{1}{c}{\texttt{SOCK\_PACKET}}& + \multicolumn{1}{c}{\texttt{SOCK\_SEQPACKET}} \\ + \texttt{PF\_UNIX} & si & si & & & \\ + \texttt{PF\_INET} & TCP & UDP & IPv4 & & \\ + \texttt{PF\_INET6} & TCP & UDP & IPv6 & & \\ + \texttt{PF\_IPX} & ? & & & & \\ + \texttt{PF\_NETLINK} & & & si & & \\ + \texttt{PF\_X25} & & & & & \\ + \texttt{PF\_AX25} & & & & & \\ + \texttt{PF\_ATMPVC} & ? & & & & \\ + \texttt{PF\_APPLETALK} & ? & & & & \\ + \texttt{PF\_PACKET} & & & & & \\ + \end{tabular} + \caption{Combinazioni valide di dominio e tipo di protocollo per la funzione \texttt{socket}.} + \label{tab:sock_sock_valid_combinations} +\end{table} + + + +\section{Le strutture degli indirizzi} +\label{sec:sock_sockaddr} + +La gran parte dei + + +\section{Le funzioni di conversione degli indirizzi} +\label{sec:sock_addr_conv} + + + + + + + + +\chapter{Socket TCP elementari} +\label{cha:elem_TCP_sock} + +Esamineremo in questo capitolo quanto necessario per capire come scrivere un +client e un server TCP, riprendendo quanto visto in \ref{sec:net_cli_sample} e +\ref{sec:net_cli_server}. + + + +\subsection{Creazione e terminazione della connessione TCP} + +Per capire il funzionamento delle funzioni della interfaccia dei socket che +operano con TCP (le varie \texttt{connect}, \texttt{accept}, \texttt{close} +che abbiamo visto negli esempi iniziali e su cui torneremo più avatni) è +fodamentale capire come funziona la creazione e la conclusione di una +connessione TCP. + +\subsection{Le porte} + + -- 2.30.2