Completata la parte su getaddinfo con delle funzioni di ausilio per chiamare
[gapil.git] / sockctrl.tex
index b4b229e3d36a761ba65ff961c6327b5a0c24f1ab..872f7b7f133babcf6be70ee733ddfe65a0d218a2 100644 (file)
@@ -1656,18 +1656,150 @@ qualora la loro dimensione ecceda quelle specificate dagli argomenti
 viene restituito invece un codice che assume gli stessi valori illustrati in
 tab.~\ref{tab:addrinfo_error_code}.
 
-A questo punto possiamo fornire degli esempi di utilizzo diretto della nuova
+A questo punto possiamo fornire degli esempi di utilizzo della nuova
 interfaccia, adottandola per le precedenti implementazioni del client e del
-server per il servizio \textit{echo}; dato che l'uso delle funzioni (in
-particolare di \func{getaddrinfo} è piuttosto complesso, prevedendo una
-impostazione manuale dell'argomento \param{hints}, provvederemo una
-interfaccia semplificata per i due casi visti finora, quello in cui si
-specifica nel client un indirizzo remoto per la connessione al server, e
-quello in cui si specifica nel server un indirizzo locale su cui porsi in
-ascolto.
-
-La prima funzione è allora \func{sockconn}, che richiede la risoluzione di un
-indirizzo e di un servizio per connettere un socket allo stesso. 
+server per il servizio \textit{echo}; dato che l'uso delle funzioni appena
+illustrate (in particolare di \func{getaddrinfo}) è piuttosto complesso,
+essendo necessaria anche una impostazione diretta dei campi dell'argomento
+\param{hints}, provvederemo una interfaccia semplificata per i due casi visti
+finora, quello in cui si specifica nel client un indirizzo remoto per la
+connessione al server, e quello in cui si specifica nel server un indirizzo
+locale su cui porsi in ascolto.
+
+La prima funzione è allora \func{sockconn} che restituisce un socket connesso
+all'indirizzo ed al servizio specificati come argomenti; la funzione prende
+poi altri due argomenti aggiuntivi per indicare il protocollo da usare ed il
+tipo di socket. Il corpo della funzione è riportato in
+fig.~\ref{fig:sockconn_code}, ed il codice completo è nel file
+\file{sockconn.c} nei sorgenti allegati alla guida.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/sockconn.c}
+  \end{minipage}
+  \normalsize
+  \caption{Il codice della funzione \func{sockconn}.}
+  \label{fig:sockconn_code}
+\end{figure}
+
+La funzione prende quattro argomenti, i primi due sono le stringhe che
+indicano il nome della macchina a cui collegarsi ed il relativo servizio;
+seguono il protocollo da usare (in forma numerica) ed il tipo di socket (al
+solito specificato con i valori illustrati in sez.~\ref{sec:sock_type}). La
+funzione ritorna il filde descriptor associato al socket in caso di successo,
+o -1 in caso di errore. Come si vede la funzione prevede anche ad alcune
+stampe in maniera diretta (il che la rende non utilizzabile all'interno di un
+demone).
+
+Una volta definite le variabili necessarie (\texttt{\small 3--5}) la funzione
+prima (\texttt{\small 7}) azzera il contenuto della struttura \var{hint} e poi
+provvede (\texttt{\small 8--10}) ad inizializzarne i valori necessari per la
+chiamata (\texttt{\small 11}) a \func{getaddrinfo}. Di quest'ultima si
+controlla (\texttt{\small 12}) il codice di ritorno, in modo da stampare
+(\texttt{\small 13--15}) un avviso di errore ed uscire in caso di errore.  Se
+la risoluzioen del nome ha successo si provvede (\texttt{\small 18--22}) ad
+aprire il socket, ed a connettersi ad esso (\texttt{\small 24--28}); in
+entrambi casi si gestisce il caso di errore. Infine prima di ritornare
+(\texttt{\small 30}) il file descriptor del socket si provvede (\texttt{\small
+  29}) a liberare le strutture \struct{addrinfo} allocate da
+\func{getaddrinfo}.
+
+Si noti come la funzione si limiti ad usare i valori contenuti nella prima
+struttura \struct{addrinfo} ritornata da \func{getaddrinfo}, non eseguendo
+ulteriori tentativi sulle successive in caso di errore. Un'altra
+caratteristica della funzione è che è del tutto irrilevante se la struttura
+ritornata usa indirizzi IPv6 o IPv4, in quanto si fa uso direttamente dei dati
+relativi alle strutture degli indirizzi di \struct{addrinfo} che sono
+\textsl{opachi} rispetto all'uso della funzione \func{connect}.
+
+Per usare questa funzione possiamo allora modificare ulteriormente il nostro
+programma client per il servizio \textit{echo}; in questo caso rispetto al
+codice usato finora per collegarsi (vedi fig.~\ref{fig:TCP_echo_client_1})
+avremo una semplificazione per cui il corpo principale del nostro client
+diventerà quello illustrato in fig.~\ref{fig:TCP_echo_fifth}, in cui le
+chiamate a \func{socket}, \func{inet\_pton} e \func{connect} sono sostituite
+da una singola chiamata a \func{sockconn}. Inoltre il nuovo client (il cui
+codice completo è nel file \file{TCP\_echo\_fifth.c} dei sorgenti allegati)
+consente di utilizzare come argomento del programma un nome a dominio al posto
+dell'indirizzo numerico, e può utilizzare sia indirizzi IPv4 che IPv6.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/TCP_echo_fifth.c}
+  \end{minipage}
+  \normalsize
+  \caption{Il nuovo codice per la connessione del client \textit{echo}.}
+  \label{fig:TCP_echo_fifth}
+\end{figure}
+
+La seconda funzione di ausilio è \func{sockbind}, il cui corpo principale è
+riportato in fig.~\ref{fig:sockbind_code} (al solito il sorgente completo è
+nel file \file{sockbind.c} dei sorgenti allegati alla guida). Come si può
+notare la funzione è del tutto analoga alla precedente \func{sockconn}, e
+prende gli stessi argomenti, però invece di eseguire una connessione con
+\func{connect} si limita a chiamare \func{bind} per collegare il socket ad una
+porta. 
+
+Dato che la funzione è pensata per utilizzata da un server ci si può chiedere
+a quale scopo mantenere l'argomento \param{host} quando l'indirizzo di questo
+è usualmente noto. Si ricordi però quanto detto in
+sez.~\ref{sec:TCP_func_bind}, relativamente al significato della scelta di un
+indirizzo specifico come argomento di \func{bind}, che consente di porre il
+server in ascolto su uno solo dei possibili diversi indirizzi presenti su di
+una macchina. 
+
+Se non si vuole che la funzione esegua \func{bind} su un indirizzo specifico,
+ma utilizzi l'indirizzo generico, occorrerà avere cura di passare un valore
+\const{NULL} come valore per l'argomento \var{host}, l'uso del valore
+\const{AI\_PASSIVE} serve ad ottenere il valore generico nella rispettiva
+struttura degli indirizzi.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/sockbind.c}
+  \end{minipage}
+  \normalsize
+  \caption{Il codice della funzione \func{sockbind}.}
+  \label{fig:sockbind_code}
+\end{figure}
+
+
+Come già detto la funzione è analoga a \func{sockconn} ed inizia azzerando ed
+inizializzando (\texttt{\small 6-11}) opportunamente la struttura \var{hint}
+con i valori ricevuti come argomenti, soltanto che in questo caso si è usata
+(\texttt{\small 8}) una impostazione specifica dei flag di \var{hint} usando
+\const{AI\_PASSIVE} per indicare che il socket sarà usato per una apertura
+passiva. Per il resto la chiamata a \func{getaddrinfo} (\texttt{\small 12-17})
+e quella a \func{socket} (\texttt{\small 19--23}) sono identiche, mentre si è
+sostituita (\texttt{\small 25--29}) la chiamata a \func{connect} con una
+chiamata a \func{bind}. La conclusione (\texttt{\small 30--31}) della funzione
+è identica. Si noti come anche in questo caso si siano inserite le stampe
+degli errori sullo standard output, nonostante la funzione possa essere
+invocata da un demone. In realtà questo non è un problema in quanto se la
+funzione non ha successo il programma deve uscire immediatamente prima di
+essere posto in background, e può quindi scrivere gli errori direttamente
+sullo standard output.
+
+Con l'uso di questa funzione si può modificare anche il codice del nostro
+server \textit{echo}, che rispetto a quanto illustrato nella versione iniziale
+di fig.~\ref{fig:TCP_echo_server_first_code} viene modificato nella forma
+riportata in fig.~\ref{fig:TCP_echod_third}. In questo caso il socket su cui
+porsi in ascolto viene ottenuto (\texttt{\small 15--18}) da \func{sockbind}
+che si cura anche della eventuale risoluzione di un indirizzo specifico sul
+quale si voglia far ascoltare il server.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/TCP_echod_third.c}
+  \end{minipage}
+  \normalsize
+  \caption{Nuovo codice per l'apertura passiva del server \textit{echo}.}
+  \label{fig:TCP_echod_third}
+\end{figure}