usato per \param{optval} ed una breve descrizione del significato delle
singole opzioni sulla sesta.
-
-Questo ci consentirà anche
-di trattare approfonditamente alcune opzioni che, nonostante siano
-classificate fra quelle generiche, hanno un significato effettivo solo per
-alcuni tipi di socket.TCP/IP. L'elenco dettagliato del significato delle
-opzioni generiche dei socket è allora il seguente:
-
-
Le descrizioni delle opzioni presenti in tab.~\ref{tab:sock_opt_socklevel}
sono estremamente sommarie, è perciò necessario fornire un po' più di
-informazioni; alcune opzioni comunque hanno una notevole rilevanza nella
+informazioni. Alcune opzioni inoltre hanno una notevole rilevanza nella
gestione dei socket, e pertanto il loro utilizzo sarà approfondito
-separatamente in sez.~\ref{sec:sock_options_main}. Quello che segue pertanto è
-soltanto un elenco più dettagliato di quanto scritto in
+separatamente in sez.~\ref{sec:sock_options_main}. Quello che segue è quindi
+soltanto un elenco più dettagliato della breve descrizione di
tab.~\ref{tab:sock_opt_socklevel} sul significato delle varie opzioni:
\begin{basedescript}{\desclabelwidth{2.5cm}\desclabelstyle{\nextlinelabel}}
+
\item[\const{SO\_KEEPALIVE}] questa opzione abilita un meccanismo di verifica
della persistenza di una connessione associata al socket (ed è pertanto
effettiva solo sui socket che supportano le connessioni, ed è usata
supportino i dati \textit{out-of-band} (non ha senso per socket UDP ad
esempio), ed utilizza per \param{optval} un intero usato come valore logico.
-
\item[\const{SO\_RCVLOWAT}] questa opzione imposta il valore che indica il
numero minimo di byte che devono essere presenti nel buffer di ricezione
perché il kernel passi i dati all'utente, restituendoli ad una \func{read} o
essere cambiato; \func{getsockopt} leggerà questo valore mentre
\func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}.
-
\item[\const{SO\_SNDLOWAT}] questa opzione imposta il valore che indica il
numero minimo di byte che devono essere presenti nel buffer di scrittura
perché il kernel li invii al protocollo successivo, consentendo ad una
sempre 1 e non può essere cambiato; \func{getsockopt} leggerà questo valore
mentre \func{setsockopt} darà un errore di \errcode{ENOPROTOOPT}.
-
\item[\const{SO\_RCVTIMEO}] l'opzione permette di impostare un tempo massimo
sulle operazioni di lettura da un socket, e prende per \param{optval} una
struttura di tipo \struct{timeval} (vedi fig.~\ref{fig:sys_timeval_struct})
socket. Maggiori dettagli sul suo funzionamento sono forniti in
sez.~\ref{sec:sock_options_main}.
-
\item[\const{SO\_TYPE}] questa opzione permette di leggere il tipo di socket
su cui si opera; funziona solo con \func{getsockopt}, ed utilizza per
\param{optval} un intero in cui verrà restituto il valore numerico che lo
su tale indirizzo. Prende per \param{optval} un intero usato come valore
logico. L'opzione non ha effetti su un socket di tipo \const{SOCK\_STREAM}.
-
\item[\const{SO\_SNDBUF}] questa opzione imposta la dimenzione del buffer di
uscita del socket. Prende per \param{optval} un intero indicante il numero
di byte. Il valore di default ed il valore massimo che si può specificare
come argomento per questa opzione sono impostabili tramiti gli opportuni
valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}).
-
\item[\const{SO\_RCVBUF}] questa opzione imposta la dimenzione del buffer di
ingresso del socket. Prende per \param{optval} un intero indicante il numero
di byte. Il valore di default ed il valore massimo che si può specificare
come argomento per questa opzione sono impostabili tramiti gli opportuni
valori di \func{sysctl} (vedi sez.~\ref{sec:sock_sysctl}).
-
\item[\const{SO\_LINGER}] questa opzione controlla le modalità con cui viene
chiuso un socket quando si utilizza un protocollo che supporta le
principalmente ai socket TCP.
Con le impostazioni di default (che sono riprese da BSD) Linux emette un
-messaggio di \textit{keep-alive} verso l'altro capo della connessione se
-questa è rimasta senza traffico per più di due ore. Se è tutto a posto il
-messaggio viene ricevuto e verrà emesso un segmento ACK di risposta, alla cui
-ricezione ripartirà un'altro ciclo di attesa per altre due ore di inattività;
-il tutto avviene all'interno del kernel e le applicazioni non riceveranno
-nessun dato.
+messaggio di \textit{keep-alive}\footnote{in sostanza un segmento ACK vuoto,
+ cui sarà risposto con un altro segmento ACK vuoto.} verso l'altro capo della
+connessione se questa è rimasta senza traffico per più di due ore. Se è tutto
+a posto il messaggio viene ricevuto e verrà emesso un segmento ACK di
+risposta, alla cui ricezione ripartirà un'altro ciclo di attesa per altre due
+ore di inattività; il tutto avviene all'interno del kernel e le applicazioni
+non riceveranno nessun dato.
In caso di problemi invece si possono avere i due casi già illustrati in
sez.~\ref{sec:TCP_conn_crash} per il caso di terminazione prococe del server:
tutti i file che aveva aperti e la relativa emissione degli opportuni
segmenti FIN nel caso dei socket.} e viene usata sui server per evitare di
mantenere impegnate le risorse dedicate a trattare delle connessioni in realtà
-terminate. Abilitandola le connessioni effettivamente terminate vengono
-chiuse ed una \func{select} potrà rilevare la conclusione delle stesse e
+terminate ad esempio perché l'altro capo è crollato senza che se ne sia
+ricevuto un avviso; quelle che vengono anche chiamate conessioni
+\textsl{semi-aperte}, in cui il server è in attesa di dati in ingresso che non
+arriveranno mai perché il client non è più attivo.
+
+Abilitandola le connessioni effettivamente terminate vengono chiuse e ad
+esempio una \func{select} potrà rilevare la conclusione delle stesse e
ricevere il relativo errore. Si tenga però presente che non si ha la certezza
assoluta che un errore di \errcode{ETIMEDOUT} corrisponda ad una reale
conclusione della connessione, il problema potrebbe essere dovuto ad un
problema di routing che perduri per un tempo maggiore di quello impiegato nei
-vari tentativi di ritrasmissione del \textit{keep-alive}.
+vari tentativi di ritrasmissione del \textit{keep-alive} (anche se questa non
+è una una condizione molto probabile).
\begin{figure}[!htb]
\footnotesize \centering
tutte le volta che un processo figlio viene eseguito in risposta ad una
connessione verrà pertanto eseguita o meno la sezione (\texttt{\small 14--17})
che esegue l'impostazione di \const{SO\_KEEPALIVE} sul socket connesso.
-
\index{\texttt{SO\_KEEPALIVE} (costante)|)}
valore, per cui in tal caso la successiva chiamata (\texttt{\small 13-17}) a
\func{setsockopt} attiverà l'opzione \const{SO\_REUSEADDR}.
-
\begin{figure}[!htb]
\footnotesize \centering
\begin{minipage}[c]{15cm}
fare questa operazionie per socket TCP dato che su di essi si può sempre
invocare \func{getsockname} una volta che si è completata la connessione.
-Infine il quarto caso è quello in si vuole effettivamente ottenere un
+Infine il quarto caso è quello in cui si vuole effettivamente ottenere un
\textit{completely duplicate binding}, quando cioè si vuole eseguire
\func{bind} su un indirizzo ed una porta che sono già \textsl{legati} ad un
altro socket. Questo ovviamente non ha senso per il normale traffico di rete,
La terza opzione da approfondire è \const{SO\_LINGER}; essa, come il nome
suggerisce, consente di ``\textsl{indugiare}'' nella chiusura di un socket. Il
-comportamento standard sia di \func{close} che \func{shutdown} è quello di
-terminare immediatamente dopo la chiamata, mentre il procedimento di chiusura
-della connessione e l'invio sulla rete di tutti i dati ancora presenti nei
-buffer viene gestito in sottofondo dal kernel.
+comportamento standard sia di \func{close} che \func{shutdown} è infatti
+quello di terminare immediatamente dopo la chiamata, mentre il procedimento di
+chiusura della connessione (o di un lato di essa) ed il rispettivo invio sulla
+rete di tutti i dati ancora presenti nei buffer, viene gestito in sottofondo
+dal kernel.
\begin{figure}[!htb]
\footnotesize \centering
\label{fig:sock_linger_struct}
\end{figure}
-L'uso di \const{SO\_LINGER} permette di modificare (ed eventualmente
-ripristinare) questo comportamento in base ai valori passati nei campi della
-stuttura \struct{linger}. Fintanto che il valore del campo \var{l\_onoff} di
-\struct{linger} è nullo la modalità che viene impostata (qualunque sia il
-valore di \var{l\_linger}) è quella standard appena illustrata.
-
-Se però si utilizza un valore di \var{l\_onoff} diverso da zero per
-l'impostazione di \const{SO\_LINGER} il comportamento dipende dal valore di
-\var{l\_linger}; se quest'ultimo è nullo l'uso delle funzioni \func{close} e
-\func{shutdown} provoca la terminazione immediata della connessione: nel caso
-di TCP cioè non viene eseguito il procedimento di chiusura illustrato in
-sez.~\ref{sec:TCP_conn_term}, ma viene inviato un segmento di RST che termina
-immediatamente la connessione. Se invece \var{l\_linger} ha un valore diverso
-da zero sia \func{close} che \func{shutdown} si bloccano e non ritornano
-fintanto che non si sia concluso il procedimento di chiusura della
-connessione, o non siano passati il numero di secondi specificati da
-\var{l\_linger}.
+L'uso di \const{SO\_LINGER} con \func{setsockopt} permette di modificare (ed
+eventualmente ripristinare) questo comportamento in base ai valori passati nei
+campi della stuttura \struct{linger}, illustrata in
+fig.~\ref{fig:sock_linger_struct}. Fintanto che il valore del campo
+\var{l\_onoff} di \struct{linger} è nullo la modalità che viene impostata
+(qualunque sia il valore di \var{l\_linger}) è quella standard appena
+illustrata; questa combinazione viene utilizzata per riportarsi al
+comportamento normale qualora esso sia stato cambiato da una precedente
+chiamata.
+
+Se però si utilizza un valore di \var{l\_onoff} diverso da zero, il
+comportamento alla chiusura viene a dipendere dal valore specificato per il
+campo \var{l\_linger}; se quest'ultimo è nullo l'uso delle funzioni
+\func{close} e \func{shutdown} provoca la terminazione immediata della
+connessione: nel caso di TCP cioè non viene eseguito il procedimento di
+chiusura illustrato in sez.~\ref{sec:TCP_conn_term}, ma tutti i dati ancora
+presenti nel buffer vengono immediatamente scartati e sulla rete viene inviato
+un segmento di RST che termina immediatamente la connessione.
+
+Un esempio di questo comportamento si può abilitare nel nostro client del
+servizio \textit{echo} utilizzando l'opzione \texttt{-r}, al solito riportiamo
+in fig.~\ref{fig:TCP_echo_sixth} solo la sezione di codice rilevante, il
+codice completo è disponibile nei sorgenti allegati.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \includecodesample{listati/TCP_echo_sixth.c}
+ \end{minipage}
+ \normalsize
+ \caption{La sezione del codice del client \textit{echo} che imposta la
+ terminazione immediata della connessione in caso di chiusura.}
+ \label{fig:TCP_echo_sixth}
+\end{figure}
+
+In questo caso la sezione indicata viene eseguita dopo aver effettuato la
+connessione e prima di chiamare la funzione di gestione, cioè fra le righe
+(\texttt{\small 12}) e (\texttt{\small 13}) del precedente esempio di
+fig.~\ref{fig:TCP_echo_fifth}. Il codice si limita semplicememente a
+controllare (\texttt{\small 3}) il valore della variabile \var{reset}
+(opportunamente impostata nella gestione delle opzioni qualora si usi
+\texttt{-r} nella chiamata del client) e nel caso impostare (\texttt{\small
+ 5--6}) gli opportuni valori della struttura \var{ling}, per poi usare questa
+nella successiva (\texttt{\small 7}) chiamata a \func{setsockopt}. Di questa
+(\texttt{\small 7--10}) viene comunque controllato il valore di ritorno ed
+eseguita la terminazione del programma in caso un eventuale errore, con stampa
+dello stesso.
+
+Infine se sia \var{l\_onoff} che \var{l\_linger} hanno un valore diverso da
+zero sia \func{close} che \func{shutdown} si bloccano eseguendo la normale
+procedura di conclusione della connessione (quella di
+sez.~\ref{sec:TCP_conn_term}) e non ritornano fintanto che non si sia concluso
+il procedimento di chiusura della connessione, o non siano passati il numero
+di secondi\footnote{questa è l'unità di misura indicata da POSIX ed adottata
+ da Linux, altri kernel possono usare unità di misura diverse, oppure usare
+ il campo \var{l\_linger} come valore logico (ignorandone il valore) per
+ rendere (quando diverso da zero) \func{close} e \func{shutdown} bloccanti
+ fino al completamento della trasmissione dei dati sul buffer.} specificati
+da \var{l\_linger}.
+
+
\index{\texttt{SO\_LINGER} (costante)|)}