Nuova versione del client
[gapil.git] / elemtcp.tex
index 585f6053803cc296a121b2e9fee9408a76ff069a..70caf59463babdf922a02ac50eeca7eb94622cbe 100644 (file)
@@ -1,6 +1,6 @@
 %% elemtcp.tex
 %%
-%% Copyright (C) 2000-2002 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2003 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Prefazione",
@@ -1328,7 +1328,7 @@ Il primo passo (\texttt{\small 14--18}) 
 \func{socket} ritorna il descrittore che viene usato per identificare il
 socket in tutte le chiamate successive. Nel caso la chiamata fallisca si
 stampa un errore (\texttt{\small 16}) con la funzione \func{perror} e si esce
-(\texttt{\small 16}) con un codice di errore.
+(\texttt{\small 17}) con un codice di errore.
 
 Il passo seguente (\texttt{\small 19--27}) è quello di costruire un'apposita
 struttura \struct{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed
@@ -1635,7 +1635,7 @@ output.
 \label{sec:TCP_echo_client}
 
 Il codice della prima versione del client per il servizio \textit{echo},
-disponibile nel file \file{TCP\_echo1.c}, è riportato in
+disponibile nel file \file{TCP\_echo\_first.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}) è
@@ -1644,7 +1644,7 @@ sostanzialmente identica, a parte l'uso di una porta diversa.
 \begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15.6 cm}
-    \includecodesample{listati/TCP_echo1.c}
+    \includecodesample{listati/TCP_echo_first.c}
   \end{minipage} 
   \normalsize
   \caption{Codice della prima versione del client \textit{echo}.}
@@ -2069,16 +2069,17 @@ Inoltre in certi casi,\footnote{Stevens in \cite{UNP1} accenna che la maggior
   di Linux questa è disponibile.} anche quando questa è presente, non è detto
 possa essere usata con \func{accept}. La portabilità però viene al costo di
 una riscrittura parziale del server, secondo quanto mostrato in
-\figref{fig:TCP_echo_server_code}.
+\figref{fig:TCP_echo_server_code}, dove si è riportata la sezione di codice
+modificata per la seconda versione del programma.
 
-\begin{figure}[!htbp]
+\begin{figure}[!htb]
   \footnotesize \centering
   \begin{minipage}[c]{15.6cm}
     \includecodesample{listati/TCP_echod.c}
   \end{minipage} 
   \normalsize
-  \caption{Codice del corpo principale della seconda versione del server
-    per il servizio \textit{echo}.}
+  \caption{Sezione del codice seconda versione del server
+    per il servizio \textit{echo} modificate rispetto alla prima.}
   \label{fig:TCP_echo_server_code}
 \end{figure}
 
@@ -2087,19 +2088,26 @@ quella ad \func{accept}, dato che questa 
 padre in stato di sleep.\footnote{si noti infatti che le altre \textit{slow
     system call} o sono chiamate prima di entrare nel ciclo principale, quando
   ancora non esistono processi figli, o sono chiamate dai figli stessi.}  Per
-questo l'unica modifica nella nuova versione del server, rispetto alla
-versione precedente vista in \figref{fig:TCP_ServEcho}, è nella sezione
-(\texttt{\small 43--48}) in cui si effettua la chiamata di \func{accept}.
-Quest'ultima allora viene effettuata (\texttt{\small 43--44}) all'interno di
-un ciclo di \code{while}\footnote{la sintassi del C relativa a questo ciclo
-  può non essere del tutto chiara. In questo caso infatti si è usato un ciclo
-  vuoto che non esegue nessuna istruzione, in questo modo quello che viene
-  ripetuto con il ciclo è soltanto il codice che esprime la condizione
-  all'interno del \code{while}.}  che la ripete indefinitamente qualora in
-caso di errore il valore di \var{errno} sia \errcode{EINTR}. Negli altri casi
-si esce in caso di errore effettivo (\texttt{\small 45--48}), altrimenti il
-programma prosegue esattamente allo stesso modo del precedente.
-
+questo l'unica modifica sostanziale nella nuova versione del server, rispetto
+alla versione precedente vista in \figref{fig:TCP_ServEcho}, è nella sezione
+(\texttt{\small 9--14}) in cui si effettua la chiamata di \func{accept}.
+Quest'ultima viene effettuata (\texttt{\small 9--10}) all'interno di un ciclo
+di \code{while}\footnote{la sintassi del C relativa a questo ciclo può non
+  essere del tutto chiara. In questo caso infatti si è usato un ciclo vuoto
+  che non esegue nessuna istruzione, in questo modo quello che viene ripetuto
+  con il ciclo è soltanto il codice che esprime la condizione all'interno del
+  \code{while}.}  che la ripete indefinitamente qualora in caso di errore il
+valore di \var{errno} sia \errcode{EINTR}. Negli altri casi si esce in caso di
+errore effettivo (\texttt{\small 11--14}), altrimenti il programma prosegue.
+
+Si noti che in questa nuova versione si è aggiunta una ulteriore sezione
+(\texttt{\small 15--28}) per il debugging, che stampa l'indirizzo da cui si è
+avuta la connessione, e la gestione (\texttt{\small 5}) di una nuova opzione,
+specificabile con \code{-w Nsec}, che inizializza la variabile \var{waiting}
+al numero di secondi da aspettare. Questa opzione permette di specificare un
+tempo di attesa prima di passare alla chiamata \func{accept}, il cui scopo
+sarà più chiaro facendo riferimento al primo degli scenari critici di
+\secref{sec:TCP_echo_critical}.
 
 
 
@@ -2114,16 +2122,19 @@ la rete 
 gestire tutta una serie di situazioni critiche che non esistono per i processi
 locali.
 
-Come accennato in \secref{sec:TCP_func_accept} la funzione \func{accept}
-riporta tutti gli eventuali errori di rete pendenti su una connessione sul
-\textit{connected socket}; questo significa che, oltre al caso di interruzione
-da parte di un segnale, esistono altri errori non fatali che necessitano
-semplicemente la ripetizione della chiamata senza che si debba uscire dal
-programma. Un esempio possibile è quello mostrato in
-\figref{fig:TCP_early_abort}, in cui la connessione viene abortita dal client
-con l'invio di un segmento RST prima che sia stata chiamata la funzione
-\func{accept}.
+La prima situazione critica è quella della terminazione precoce, causata da un
+qualche errore sulla rete, della connessione effettuata da un client. Come
+accennato in \secref{sec:TCP_func_accept} la funzione \func{accept} riporta
+tutti gli eventuali errori di rete pendenti su una connessione sul
+\textit{connected socket}. Di norma questo non è un problema, in quanto non
+appena completata la connessione, \func{accept} ritorna e l'errore sarà
+rilevato in seguito dal processo che gestisce la connessione alla prima
+chiamata di una funzione che opera sul socket..
 
+È però possibile, dal punto di vista teorico, incorrere anche in uno scenario
+del tipo di quello mostrato in \figref{fig:TCP_early_abort}, in cui la
+connessione viene abortita sul lato client con l'invio di un segmento RST,
+prima che nel server sia stata chiamata la funzione \func{accept}.
 
 \begin{figure}[htb]
   \centering
@@ -2132,6 +2143,38 @@ con l'invio di un segmento RST prima che sia stata chiamata la funzione
   \label{fig:TCP_early_abort}
 \end{figure}
 
+Benché questo non sia un fatto comune, un evento simile può essere osservato
+con dei server molto occupati. In tal caso, con una struttura del server
+simile a quella del nostro esempio, in cui la gestione delle singole
+connessioni è demandata a processi figli, può accadere che il three way
+handshake venga completato e la relativa connessione abortita subito dopo,
+prima che il padre, per via del carico della macchina, abbia fatto in tempo a
+rieseguire la chiamata ad \func{accept}. Di nuovo si ha una situazione analoga
+a quella illustrata in \figref{fig:TCP_early_abort}, in cui la connessione
+viene stabilita, ma subito dopo si ha una condizione di errore che la chiude
+prima che essa sia stata accettata dal programma.
+
+Questo significa che, oltre alla interruzione da parte di un segnale, che
+abbiamo trattato in \secref{sec:TCP_child_hand} nel caso particolare di
+\const{SIGCHLD}, si possono ricevere altri errori non fatali all'uscita di
+\func{accept}, che come nel caso precedente, necessitano semplicemente la
+ripetizione della chiamata senza che si debba uscire dal programma. In questo
+caso anche la versione modificata del nostro server non sarebbe adatta, in
+quanto uno di questi errori causerebbe la terminazione dello stesso.
+
+Si tenga presente che questo tipo di terminazione non è riproducibile
+terminando il client prima della chiamata ad \func{accept}; in tal caso
+infatti il socket associato alla connessione viene semplicemente chiuso,
+attraverso la sequenza vista in \secref{sec:TCP_conn_term}, per cui la
+\func{accept} ritornerà senza errori, e si avrà semplicemente un end-of-file
+al primo accesso al socket. Per riprodurre l'errore occorrerebbe usare
+l'opzione \const{SO\_LINGER} (vedi \secref{sec:xxx}) per chiedere al client di
+chiudere il socket con un segmento RST, invece che con la normale sequenza di
+chiusura.
+
+
+
+
 
 
 %%% Local Variables: