%% Copyright (C) 2000-2004 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",
+%% Free Software Foundation; with the Invariant Sections being "Un preambolo",
%% with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the
%% license is included in the section entitled "GNU Free Documentation
%% License".
l'altro capo è stato chiuso, e quindi non sarà più possibile leggere niente) e
pertanto si ritorna senza aver concluso la lettura di tutti i byte
richiesti. Entrambe le funzioni restituiscono 0 in caso di successo, ed un
-valore negativo in caso di errore, \texttt{FullRead} restituisce il numero di
+valore negativo in caso di errore, \func{FullRead} restituisce il numero di
byte non letti in caso di end-of-file prematuro.
l'ora locale della macchina a cui si effettua la richiesta, e che è assegnato
alla porta 13.
-In fig.~\ref{fig:TCP_daytime_client_code} è riportata la sezione principale del
-codice del nostro client. Il sorgente completo del programma
-(\file{TCP\_daytime.c}, che comprende il trattamento delle opzioni ed una
+In fig.~\ref{fig:TCP_daytime_client_code} è riportata la sezione principale
+del codice del nostro client. Il sorgente completo del programma
+(\texttt{TCP\_daytime.c}, che comprende il trattamento delle opzioni ed una
funzione per stampare un messaggio di aiuto) è allegato alla guida nella
sezione dei codici sorgente e può essere compilato su una qualunque macchina
GNU/Linux.
primo esempio realizzeremo un server iterativo, in grado di fornire una sola
risposta alla volta. Il codice del programma è nuovamente mostrato in
fig.~\ref{fig:TCP_daytime_iter_server_code}, il sorgente completo
-(\file{TCP\_iter\_daytimed.c}) è allegato insieme agli altri file degli esempi.
+(\texttt{TCP\_iter\_daytimed.c}) è allegato insieme agli altri file degli
+esempi.
\begin{figure}[!htbp]
\footnotesize \centering
codice, in cui si sono tralasciati il trattamento delle opzioni e le parti
rimaste invariate rispetto al precedente esempio (cioè tutta la parte
riguardante l'apertura passiva del socket). Al solito il sorgente completo del
-server, nel file \file{TCP\_cunc\_daytimed.c}, è allegato insieme ai sorgenti
-degli altri esempi.
+server, nel file \texttt{TCP\_cunc\_daytimed.c}, è allegato insieme ai
+sorgenti degli altri esempi.
\begin{figure}[!htb]
\footnotesize \centering
\label{sec:TCP_echo_client}
Il codice della prima versione del client per il servizio \textit{echo},
-disponibile nel file \file{TCP\_echo\_first.c}, è riportato in
+disponibile nel file \texttt{TCP\_echo\_first.c}, è riportato in
fig.~\ref{fig:TCP_echo_client_1}. Esso ricalca la struttura del precedente
client per il servizio \textit{daytime} (vedi
-sez.~\ref{sec:TCP_daytime_client}), e la prima parte (\texttt{\small 10--27}) è
-sostanzialmente identica, a parte l'uso di una porta diversa.
+sez.~\ref{sec:TCP_daytime_client}), e la prima parte (\texttt{\small 10--27})
+è sostanzialmente identica, a parte l'uso di una porta diversa.
\begin{figure}[!htb]
\footnotesize \centering
\subsection{Il server \textit{echo}: prima versione}
\label{sec:TCPsimp_server_main}
-La prima versione del server, contenuta nel file \file{TCP\_echod\_first.c}, è
-riportata in fig.~\ref{fig:TCP_echo_server_first_code}. Come abbiamo fatto per
-il client anche il server è stato diviso in un corpo principale, costituito
-dalla funzione \code{main}, che è molto simile a quello visto nel precedente
-esempio per il server del servizio \textit{daytime} di
+La prima versione del server, contenuta nel file \texttt{TCP\_echod\_first.c},
+è riportata in fig.~\ref{fig:TCP_echo_server_first_code}. Come abbiamo fatto
+per il client anche il server è stato diviso in un corpo principale,
+costituito dalla funzione \code{main}, che è molto simile a quello visto nel
+precedente esempio per il server del servizio \textit{daytime} di
sez.~\ref{sec:TCP_daytime_cunc_server}, e da una funzione ausiliaria
\code{ServEcho} che si cura della gestione del servizio.
introdotte una serie di nuove opzioni che ci saranno utili per il debug, è
mostrata in fig.~\ref{fig:TCP_echo_server_code_second}, dove si sono riportate
la sezioni di codice modificate nella seconda versione del programma, il
-codice completo di quest'ultimo si trova nel file \file{TCP\_echod\_second.c}
-dei sorgenti allegati alla guida.
+codice completo di quest'ultimo si trova nel file
+\texttt{TCP\_echod\_second.c} dei sorgenti allegati alla guida.
La prima modifica effettuata è stata quella di introdurre una nuova opzione a
riga di comando, \texttt{-c}, che permette di richiedere il comportamento
Il risultato finale qui dipende dall'implementazione dello stack TCP, e nel
caso di Linux anche dall'impostazione di alcuni dei parametri di sistema che
si trovano in \file{/proc/sys/net/ipv4}, che ne controllano il comportamento:
-in questo caso in particolare da \file{tcp\_retries2}. Questo parametro
-infatti specifica il numero di volte che deve essere ritentata la
-ritrasmissione di un pacchetto nel mezzo di una connessione prima di riportare
-un errore di timeout. Il valore preimpostato è pari a 15, il che
-comporterebbe 15 tentativi di ritrasmissione, ma nel nostro caso le cose sono
-andate diversamente, dato che le ritrasmissioni registrate da \cmd{tcpdump}
-sono solo 8; inoltre l'errore riportato all'uscita del client non è stato
-\errcode{ETIMEDOUT}, come dovrebbe essere in questo caso, ma
-\errcode{EHOSTUNREACH}.
+in questo caso in particolare da \file{tcp\_retries2} (vedi
+sez.~\ref{sec:sock_sysctl}). Questo parametro infatti specifica il numero di
+volte che deve essere ritentata la ritrasmissione di un pacchetto nel mezzo di
+una connessione prima di riportare un errore di timeout. Il valore
+preimpostato è pari a 15, il che comporterebbe 15 tentativi di ritrasmissione,
+ma nel nostro caso le cose sono andate diversamente, dato che le
+ritrasmissioni registrate da \cmd{tcpdump} sono solo 8; inoltre l'errore
+riportato all'uscita del client non è stato \errcode{ETIMEDOUT}, come dovrebbe
+essere in questo caso, ma \errcode{EHOSTUNREACH}.
Per capire l'accaduto continuiamo ad analizzare l'output di \cmd{tcpdump}:
esso ci mostra che a un certo punto i tentativi di ritrasmissione del
si vuole che il client sia in grado di accorgersi del crollo del server anche
quando non sta effettuando uno scambio di dati, è possibile usare una
impostazione speciale del socket (ci torneremo in
-sez.~\ref{sec:TCP_sock_options}) che provvede all'esecuzione di questo
+sez.~\ref{sec:sock_generic_options}) che provvede all'esecuzione di questo
controllo.
\section{L'uso dell'I/O multiplexing}
sufficiente a superare il valore di una \textsl{soglia di basso livello} (il
cosiddetto \textit{low watermark}). Questo valore è espresso in numero di
byte e può essere impostato con l'opzione del socket \const{SO\_RCVLOWAT}
- (tratteremo le opzioni dei socket in sez.~\ref{sec:TCP_sock_options}); il
- suo valore di default è 1 per i socket TCP e UDP. In questo caso una
+ (tratteremo l'uso di questa opzione in sez.~\ref{sec:sock_generic_options});
+ il suo valore di default è 1 per i socket TCP e UDP. In questo caso una
operazione di lettura avrà successo e leggerà un numero di byte maggiore di
zero.
\item il lato in lettura della connessione è stato chiuso; si è cioè ricevuto
\item c'è stato un errore sul socket. In questo caso una operazione di lettura
non si bloccherà ma restituirà una condizione di errore (ad esempio
\func{read} restituirà -1) e imposterà la variabile \var{errno} al relativo
- valore. Vedremo in sez.~\ref{sec:TCP_sock_options} come sia possibile
+ valore. Vedremo in sez.~\ref{sec:sock_generic_options} come sia possibile
estrarre e cancellare errori pendenti su un socket usando l'opzione
\const{SO\_ERROR}.
\item quando si sta utilizzando un \textit{listening socket} ed ci sono delle
valore della \textsl{soglia di basso livello} in scrittura ed inoltre o il
socket è già connesso o non necessita (ad esempio è UDP) di connessione. Il
valore della soglia è espresso in numero di byte e può essere impostato con
- l'opzione del socket \const{SO\_SNDLOWAT}; il suo valore di default è 2048
- per i socket TCP e UDP. In questo caso una operazione di scrittura non si
+ l'opzione del socket \const{SO\_SNDLOWAT} (trattata in
+ sez.~\ref{sec:sock_generic_options}); il suo valore di default è 2048 per i
+ socket TCP e UDP. In questo caso una operazione di scrittura non si
bloccherà e restituirà un valore positivo pari al numero di byte accettati
dal livello di trasporto.
\item il lato in scrittura della connessione è stato chiuso. In questo caso
\item c'è stato un errore sul socket. In questo caso una operazione di
scrittura non si bloccherà ma restituirà una condizione di errore ed
imposterà opportunamente la variabile \var{errno}. Vedremo in
- sez.~\ref{sec:TCP_sock_options} come sia possibile estrarre e cancellare
+ sez.~\ref{sec:sock_generic_options} come sia possibile estrarre e cancellare
errori pendenti su un socket usando l'opzione \const{SO\_ERROR}.
\end{itemize*}
suppone che il programma server non venga terminato correttamente, ma si
blocchi tutto senza la possibilità di avere l'emissione di un segmento FIN che
segnala la terminazione della connessione. Di nuovo fintanto che la
-connessione non si riattiva )con il riavvio della macchina del server) il
+connessione non si riattiva (con il riavvio della macchina del server) il
client non è in grado di fare altro che accettare dell'input e tentare di
inviarlo. La differenza in questo caso è che non appena la connessione
ridiventa attiva i dati verranno sì trasmessi, ma essendo state perse tutte le
\label{fig:TCP_ClientEcho}
\end{figure}
-Si è allora riportato in fig.~\ref{fig:TCP_ClientEcho} la versione finale della
-nostra funzione \func{ClientEcho}, in grado di gestire correttamente l'intero
-flusso di dati fra client e server. Il codice completo del client,
+Si è allora riportato in fig.~\ref{fig:TCP_ClientEcho} la versione finale
+della nostra funzione \func{ClientEcho}, in grado di gestire correttamente
+l'intero flusso di dati fra client e server. Il codice completo del client,
comprendente la gestione delle opzioni a riga di comando e le istruzioni per
-la creazione della connessione, si trova nel file \file{TCP\_echo.c},
-distribuito coi sorgenti allegati alla guida.
+la creazione della connessione, si trova nel file
+\texttt{TCP\_echo\_fourth.c}, distribuito coi sorgenti allegati alla guida.
La nuova versione è molto simile alla precedente di
fig.~\ref{fig:TCP_ClientEcho_third}; la prima differenza è l'introduzione
il traffico nella suddivisione fra dati normali e prioritari. In generale
pertanto:
\begin{itemize}
-\item i dati trasmessi su un socket vengono considerati traffico normale,
- pertanto vengono rilevati da una selezione con \const{POLLIN} o
- \const{POLLRDNORM}.
+\item i dati inviati su un socket vengono considerati traffico normale,
+ pertanto vengono rilevati alla loro ricezione sull'altro capo da una
+ selezione effettuata con \const{POLLIN} o \const{POLLRDNORM};
\item i dati \textit{out-of-band} su un socket TCP vengono considerati
traffico prioritario e vengono rilevati da una condizione \const{POLLIN},
\const{POLLPRI} o \const{POLLRDBAND}.
viene considerato traffico normale, pertanto viene rilevato da una
condizione \const{POLLIN} o \const{POLLRDNORM}, ma una conseguente chiamata
a \func{read} restituirà 0.
+\item la disponibilità di spazio sul socket per la scrittura di dati viene
+ segnalata con una condizione \const{POLLOUT}.
+\item quando uno dei due capi del socket chiude un suo lato della connessione
+ con \func{shutdown} si riceve una condizione di \const{POLLHUP}.
\item la presenza di un errore sul socket (sia dovuta ad un segmento RST che a
timeout) viene considerata traffico normale, ma viene segnalata anche dalla
condizione \const{POLLERR}.
In fig.~\ref{fig:TCP_PollEchod} è riportata la sezione principale della nuova
versione del server, la versione completa del codice è riportata nel file
-\file{poll\_echod.c} dei sorgenti allegati alla guida. Al solito nella figura
-si sono tralasciate la gestione delle opzioni, la creazione del socket in
-ascolto, la cessione dei privilegi e le operazioni necessarie a far funzionare
-il programma come demone, privilegiando la sezione principale del programma.
+\texttt{poll\_echod.c} dei sorgenti allegati alla guida. Al solito nella
+figura si sono tralasciate la gestione delle opzioni, la creazione del socket
+in ascolto, la cessione dei privilegi e le operazioni necessarie a far
+funzionare il programma come demone, privilegiando la sezione principale del
+programma.
Come per il precedente server basato su \func{select} il primo passo
(\texttt{\small 2--8}) è quello di inizializzare le variabili necessarie. Dato