elementare, in cui il flusso dei dati va solo nella direzione dal server al
client. In questa sezione esamineremo un esempio di applicazione client/server
un po' più complessa, che usi i socket TCP per una comunicazione in entrambe
-le direzioni, implementando il servizio standard \textit{echo}, così come
-definito dall'\href{http://www.ietf.org/rfc/rfc0862.txt}{RFC~862}.
-
-Si è scelto, seguendo l'esempio di \cite{UNP1}, di usare questo servizio, che
-si limita a restituire in uscita quanto immesso in ingresso, perché nonostante
-la sua estrema semplicità costituisce il prototipo ideale di una generica
-applicazione di rete in cui un server risponde alle richieste di un client;
-nel caso di una applicazione più complessa si potrà avere in più una
-elaborazione dell'input del client da parte del server nel fornire le risposte
-in uscita.
-
-Ci limiteremo per ora ad una implementazione elementare, che usi solo le
-funzioni di base, ma prenderemo in esame, oltre al comportamento in condizioni
-normali, anche tutti i possibili scenari particolari (errori, sconnessione
-della rete, crash del client o del server durante la connessione) che possono
-avere luogo durante l'impiego di un'applicazione di rete, partendo da una
-versione primitiva che dovrà essere rimaneggiata di volta in volta per poter
-tenere conto di tutte le evenienze che si possono manifestare nella vita reale
-di un'applicazione di rete, fino ad arrivare ad un'implementazione completa.
+le direzioni.
+
+Ci limiteremo a fornire una implementazione elementare, che usi solo le
+funzioni di base viste finore, ma prenderemo in esame, oltre al comportamento
+in condizioni normali, anche tutti i possibili scenari particolari (errori,
+sconnessione della rete, crash del client o del server durante la connessione)
+che possono avere luogo durante l'impiego di un'applicazione di rete, partendo
+da una versione primitiva che dovrà essere rimaneggiata di volta in volta per
+poter tenere conto di tutte le evenienze che si possono manifestare nella vita
+reale di un'applicazione di rete, fino ad arrivare ad un'implementazione
+completa.
+
+
+\subsection{Il servizio \textit{echo}}
+\label{sec:TCP_echo}
+
+
+Nella ricerca di un servizio che potesse fare da esempio per una comunicazione
+bidirezionale, si è deciso, seguendo la scelta di Stevens in \cite{UNP1}, di
+usare il servizio \textit{echo}, che si limita a restituire in uscita quanto
+immesso in ingresso. Infatti, nonostante la sua estrema semplicità, questo
+servizio costituisce il prototipo ideale per una generica applicazione di rete
+in cui un server risponde alle richieste di un client. Nel caso di una
+applicazione più complessa quello che si potrà avere in più è una elaborazione
+dell'input del client, che in molti casi viene interpretato come un comando,
+da parte di un server che risponde fornendo altri dati in uscita.
+
+Il servizio \textit{echo} è uno dei servizi standard solitamente provvisti
+direttamente dal superserver \cmd{inetd}, ed è definito
+dall'\href{http://www.ietf.org/rfc/rfc0862.txt}{RFC~862}. Come dice il nome il
+servizio deve rimandare indietro sulla connessione i dati che gli vengono
+inviati; l'RFC descrive le specifiche sia per TCP che UDP, e per il primo
+stabilisce che una volta stabilita la connessione ogni dato in ingresso deve
+essere rimandato in uscita, fintanto che il chiamante non ha chiude la
+connessione; il servizio opera sulla porta 7.
+
+Nel nostro caso l'esempio sarà costituito da un client che legge una linea di
+caratteri dallo standard input e la scrive sul server. A sua volta il server
+leggerà la linea dalla connessione e la riscriverà immutata all'indietro. Sarà
+compito del client leggere la risposta del server e stamparla sullo standard
+output.
\subsection{Il client: prima versione}
\label{sec:TCP_echo_client}
-Il codice della prima versione client per il servizio \textit{echo} è
-riportato in \figref{fig:TCP_echo_client_1}. Esso ricalca la struttura del
-precedente client per il servizio \textit{daytime} (vedi
+Il codice della prima versione client per il servizio \textit{echo},
+diponibile nel file \file{TCP_echo1.c}, è riportato in
+\figref{fig:TCP_echo_client_1}. Esso ricalca la struttura del precedente
+client per il servizio \textit{daytime} (vedi
\secref{sec:TCP_daytime_client}), e la prima parte (\texttt{\small 10--27}) è
sostanzialmente identica, a parte l'uso di una porta diversa.
Al solito si è tralasciata la sezione relativa alla gestione delle opzioni a
riga di comando; una volta dichiarate le variabili, si prosegue
-(\texttt{\small 10--13}) con della creazione del socket, la preparazione
-(\texttt{\small 14--17}) la struttura per l'indirizzo, con la relativa
-conversione (\texttt{\small 18--22}) di quanto specificato a riga di comando.
-
-A questo punto (\texttt{\small 23--27}) si può eseguire la connessione al
-server secondo la stessa modalità usata in \secref{sec:TCP_daytime_client}.
-Completata la connessione, al ritorno di \func{connect}, si usa la funzione
-\code{ClientEcho}, il cui codice è riportato in
-\figref{fig:TCPsimpl_client_echo_sub}. Questa si preoccupa di gestire tutta la
-comunicazione, leggendo una riga alla volta dallo standard input \file{stdin},
-scrivendola sul socket e ristampando su \file{stdout} quanto ricevuto in
-risposta dal server. Al ritorno dalla funzione (\texttt{\small 30--31}) anche
-il programma termina.
+(\texttt{\small 10--13}) con della creazione del socket, con l'usuale
+controllo degli errori, la preparazione (\texttt{\small 14--17}) della
+struttura dell'indirizzo, che usa la porta 7 riservata al servizio
+\textit{echo}, l'indirizzo specificato a riga di comando appositamente
+convertito (\texttt{\small 18--22}). Una volta inizializzato l'indirizzo si si
+può eseguire (\texttt{\small 23--27}) la connessione al server secondo la
+stessa modalità usata in \secref{sec:TCP_daytime_client}.
+
+Completata la connessione, al ritorno di \func{connect}, per gestire il
+funzionamento del protocollo si usa la funzione \code{ClientEcho}, il cui
+codice si è riportato a parte in \figref{fig:TCPsimpl_client_echo_sub}. Questa
+si preoccupa di gestire tutta la comunicazione, leggendo una riga alla volta
+dallo standard input \file{stdin}, scrivendola sul socket e ristampando su
+\file{stdout} quanto ricevuto in risposta dal server. Al ritorno dalla
+funzione (\texttt{\small 30--31}) anche il programma termina.
+
+La funzione \code{ClientEcho} utilizza due buffer (\texttt{\small 3}) per
+gestire i dati inviati e letti sul socket. La comunicazione viene gestita
+all'interno di un ciclo (\texttt{\small 5--10}), i dati da inviare sulla
+connessione vengono presi dallo \file{stdin} usando la funzione \func{fgets},
+che legge una linea di testo (terminata da un \texttt{CR} e fino al massimo di
+\const{MAXLINE} caratteri) e la salva sul buffer di invio.
+
+Si usa poi (\texttt{\small 6}) la funzione \func{FullWrite}, vista in
+\secref{sec:sock_io_behav}, per scrivere i dati sul socket, gestendo
+automaticamente l'invio multiplo qualora una singola \func{write} non sia
+sufficiente. I dati vengono riletti indietro (\texttt{\small 7}) con una
+\func{FullRead} sul buffer di ricezione e viene inserita (\texttt{\small 8})
+la terminazione della stringa e per poter usare (\texttt{\small 9}) la
+funzione \func{fputs} per scriverli su \file{stdout}.
\begin{figure}[!htb]
\footnotesize \centering
\label{fig:TCPsimpl_client_echo_sub}
\end{figure}
-La funzione \code{ClientEcho} utilizza due buffer (\texttt{\small 3}) per
-gestire i dati inviati e letti sul socket. La comunicazione viene gestita
-all'interno di un ciclo (\texttt{\small 5--10}), i dati da inviare sulla
-connessione vengono presi dallo \file{stdin} usando la funzione \func{fgets},
-trattata in \secref{sec:file_line_io}, che legge una linea di testo (terminata
-da un \texttt{CR} e fino al massimo di \const{MAXLINE} caratteri) e la salva
-sul buffer di invio, la funzione \func{FullWrite}, già vista in
-\figref{fig:sock_FullWrite_code}, scrive (\texttt{\small 6}) i dati sul socket
-(gestendo l'invio multiplo qualora una singola \func{write} non basti, come
-spiegato in \secref{sec:sock_io_behav}).
-
-I dati vengono riletti indietro (\texttt{\small 7}) con una \func{FullRead}
-sul buffer di ricezione e viene inserita (\texttt{\small 8}) la terminazione
-della stringa e per poter usare (\texttt{\small 9}) la funzione \func{fputs}
-per scriverli su \file{stdout}.
-
-Un end-of-file inviato su \file{stdin} (ad esempio con la pressione di
-\texttt{C-d}) causa il ritorno di \func{fgets} con un puntatore nullo e la
-conseguente uscita dal ciclo, al che la subroutine ritorna ed il client esce.
+Quando si conluderà l'invio di dati mandando un end-of-file sullo standard
+inputo (ad esempio con la pressione di \texttt{C-d}) si avrà il ritorno di
+\func{fgets} con un puntatore nullo (si riveda quanto spiegato in
+\secref{sec:file_line_io}) e la conseguente uscita dal ciclo; al che la
+subroutine ritorna ed il nostro programma client termina.
\subsection{Il server: prima versione}
\label{sec:TCPsimp_server_main}
-Il servizio \textit{echo} è uno dei servizi standard solitamente provvisti
-direttamente dal superserver \cmd{inetd}, ed è definito
-dall'\href{http://www.ietf.org/rfc/rfc0862.txt}{RFC~862}. Come dice il nome il
-servizio deve rimandare indietro sulla connessione i dati che gli vengono
-inviati; l'RFC descrive le specifiche sia per TCP che UDP, e per il primo
-stabilisce che una volta stabilita la connessione ogni dato in ingresso deve
-essere rimandato in uscita, fintanto che il chiamante non ha chiude la
-connessione; il servizio opera sulla porta 7.
-
-Nel nostro caso l'esempio sarà costituito da un client che legge una linea di
-caratteri dallo standard input e la scrive sul server, il server leggerà la
-linea dalla connessione e la riscriverà all'indietro; sarà compito del client
-leggere la risposta del server e stamparla sullo standard output.
-
-La prima versione del server, \file{ElemEchoTCPServer.c}, si compone di un
+La prima versione del server, \file{TCP_echod.c}, si compone di un
corpo principale, costituito dalla funzione \code{main}. Questa si incarica
di creare il socket, metterlo in ascolto di connessioni in arrivo e creare un
processo figlio a cui delegare la gestione di ciascuna connessione. Questa