X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=sockctrl.tex;h=872f7b7f133babcf6be70ee733ddfe65a0d218a2;hp=b4b229e3d36a761ba65ff961c6327b5a0c24f1ab;hb=8654ce33b450ae7bb34c3907835000a0760c2931;hpb=88d8a251947f948094d35de596feaf49e975f91b diff --git a/sockctrl.tex b/sockctrl.tex index b4b229e..872f7b7 100644 --- a/sockctrl.tex +++ b/sockctrl.tex @@ -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}