3 %% Copyright (C) 2003 Simone Piccardi. Permission is granted to
4 %% copy, distribute and/or modify this document under the terms of the GNU Free
5 %% Documentation License, Version 1.1 or any later version published by the
6 %% Free Software Foundation; with the Invariant Sections being "Prefazione",
7 %% with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the
8 %% license is included in the section entitled "GNU Free Documentation
11 \chapter{Socket TCP avanzati}
12 \label{cha:TCP_advanced}
14 Esamineremo in questo capitolo le funzionalità più evolute della gestione dei
19 \section{Socket multiplexing}
20 \label{sec:TCP_sock_multiplexing}
22 Affronteremo in questa sezione l'utilizzo dell'I/O multiplexing, affrontato in
23 \secref{sec:file_multiplexing}, nell'ambito delle applicazioni di rete. Già in
24 \ref{sec:TCP_server_crash} era emerso il problema relativo al client del
25 servizio echo che non era in grado di accorgersi della terminazione precoce
26 del server essendo bloccato nella lettura dei dati immessi da tastiera.
28 Abbiamo visto in \secref{sec:file_multiplexing} quali sono le funzionalità del
29 sistema che ci permettono di tenere sotto controllo più file descriptor in
30 contemporanea; in quella occasione non abbiamo fatto esempi, in quanto quando
31 si tratta con file normali questa tipologia di I/O non viene usata, è invece
32 un caso tipico delle applicazioni di rete quello di dover gestire varie
33 connessioni da cui possono arrivare dati comuni in maniera asincrona, per cui
34 riprenderemo l'argomento in questa sezione.
38 \subsection{Il comportamento della funzione \func{select} con i socket.}
39 \label{sec:TCP_sock_select}
41 Iniziamo con la prima delle funzioni usate per l'I/O multiplexing,
42 \func{select}, il suo funzionamento è già stato descritto in dettaglio in
43 \secref{sec:file_multiplexing} e non staremo a ripetere quanto detto lì;
44 sappiamo che la funzione ritorna quando uno o più dei file descriptor messi
45 sotto controllo è pronto per la relativa operazione.
47 In quell'occasione non abbiamo però definito cosa si intende per pronto,
48 infatti per dei normali file, o anche per delle pipe, la condizione di essere
49 pronti per la lettura o la scrittura è ovvia, lo è un po' meno di meno nel
50 caso dei socket, visto che intervengono tutte le possibili condizioni dovute
51 alla rete. Occorre allora specificare quali sono le condizioni in cui un
52 socket risulta \textsl{pronto} quando viene passato come membro di uno dei tre
53 \textit{file descriptor set} usati da \func{select}.
55 Le condizioni che fanno si che la funzione \func{select} ritorni segnalando
56 che un socket (che sarà riportato nel primo insieme di file descriptor) è
57 pronto per la lettura sono le seguenti:
59 \item nel buffer di ricezione del socket sono arrivati dei dati in quantità
60 sufficiente a superare il valore di una \textsl{soglia di basso livello} (il
61 cosiddetto \textit{low watermark}). Questo valore è espresso in numero di
62 byte e può essere impostato con l'opzione del socket \const{SO\_RCVLOWAT}
63 (tratteremo le opzioni dei socket in \secref{sec:TCP_sock_options}); il suo
64 valore di default è 1 per i socket TCP e UDP. In questo caso una operazione
65 di lettura avrà successo e leggerà un numero di byte maggiore di zero.
66 \item il lato in lettura della connessione è stato chiuso; si è cioè ricevuto
67 un segmento FIN (si ricordi quanto illustrato in \secref{sec:TCP_conn_term})
68 sulla connessione. In questo caso una operazione di lettura avrà successo,
69 ma non risulteranno presenti dati (in sostanza \func{read} ritornerà con un
70 valore nullo) per indicare la condizione di end-of-file.
71 \item c'è stato un errore sul socket. In questo caso una operazione di lettura
72 non si bloccherà ma restituirà una condizione di errore (ad esempio
73 \func{read} restituirà -1) e imposterà la variabile \var{errno} al relativo
74 valore. Vedremo in \secref{sec:TCP_sock_options} come sia possibile estrarre
75 e cancellare errori pendenti su un socket usando l'opzione
77 \item quando si sta utilizzando un \textit{listening socket} ed ci sono delle
78 connessioni completate. In questo caso la funzione \func{accept} non si
79 bloccherà.\footnote{in realtà questo non è sempre vero, come accennato in
80 \secref{sec:TCP_conn_early_abort} una connessione può essere abortita
81 dalla ricezione di un segmento RST una volta che è stata completata,
82 allora se questo avviene dopo che \func{select} è ritornata, ma prima
83 della chiamata ad \func{accept} quest'ultima, in assenza di altre
84 connessiioni, potrà bloccarsi.}
87 Le condizioni che fanno si che la funzione \func{select} ritorni segnalando
88 che un socket (che sarà riportato nel secondo insieme di file descriptor) è
89 pronto per la scrittura sono le seguenti:
91 \item nel buffer di invio è disponibile una quantità di spazio superiore al
92 valore della \textsl{soglia di basso livello} in scrittura ed inoltre o il
93 socket è già connesso o non necessita (ad esempio è UDP) di connessione. Il
94 valore della soglia è espresso in numero di byte e può essere impostato con
95 l'opzione del socket \const{SO\_SNDLOWAT}; il suo valore di default è 2048
96 per i socket TCP e UDP. In questo caso una operazione di scrittura non si
97 bloccherà e restituirà un valore positivo pari al numero di byte accettati
98 dal livello di trasporto.
99 \item il lato in scrittura della connessione è stato chiuso. In questo caso
100 una operazione di scrittura sul socket genererà il segnale \const{SIGPIPE}.
101 \item c'è stato un errore sul socket. In questo caso una operazione di
102 scrittura non si bloccherà ma restituirà una condizione di errore ed
103 imposterà opportunamente la variabile \var{errno}. Vedremo in
104 \secref{sec:TCP_sock_options} come sia possibile estrarre e cancellare
105 errori pendenti su un socket usando l'opzione \const{SO\_ERROR}.
108 Infine c'è una sola condizione che fa si che \func{select} ritorni segnalando
109 che un socket (che sarà riportato nel terzo insieme di file descriptor) ha una
110 condizione di eccezione pendente, e cioè la ricezione sul socket di dati
111 \textsl{fuori banda} (o \textit{out-of-band}), una caratteristica specifica
112 dei socket TCP su cui torneremo in \secref{sec:TCP_outofband}.
114 Si noti come nel caso della lettura \func{select} si applichi anche ad
115 operazioni che non hanno nulla a che fare con l'I/O come il riconoscimento
116 della presenza di connessioni pronte, in modo da consentire l'utilizzo di
117 \func{accept} in modalità non bloccante. Si noti infine come in caso di errore
118 un socket venga sempre riportato come pronto sia per la lettura che per la
121 Lo scopo dei due valori di soglia per i buffer di ricezione e di invio è
122 quello di consentire maggiore flessibilità nell'uso di \func{select} da parte
123 dei programmi, se infatti si sa che una applicazione non è in grado di fare
124 niente fintanto che non può ricevere o inviare una certa quantità di dati, si
125 possono utilizzare questi valori per far si che \func{select} ritorni solo
126 quando c'è la certezza di avere dati a sufficienza.\footnote{questo tipo di
127 controllo è utile di norma solo per la lettura, in quanto in genere le
128 operazioni di scrittura sono già controllate dall'applicazione, che sà
129 sempre quanti dati invia, mentre non è detto possa conoscere la quantità di
130 dati in ricezione; per cui, nella situazione in cui si conosce almeno un
131 valore minimo, per evitare la penalizzazione dovuta alla ripetizione delle
132 operazioni di lettura quando per accumulare dati sufficienti, si può
133 lasciare al kernel il compito di impostare un minimo al di sotto del quale
134 il file descriptor, pur avendo disponibili dei dati, non viene letto.}
139 \section{Le opzioni dei socket}
140 \label{sec:TCP_sock_options}
142 Dato che la maggior parte delle opzioni dei socket sono relative ai socket
143 TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
144 preferito trattare l'argomento in generale in questa sezione piuttosto che
145 nel capitolo dedicato alla trattazione generica dei socket.
149 \section{I dati \textit{out-of-band}}
150 \label{sec:TCP_outofband}
152 Una caratteristica speciale dei socket TCP è quella della presenza dei
153 cosiddetti dati \textit{out-of-band}
157 \subsection{La funzione \func{shutdown}}
158 \label{sec:TCP_shutdown}
160 Come spiegato in \secref{sec:TCP_conn_term} il procedimento di chiusura di un
161 socket TCP prevede che da entrambe le parti venga emesso un segmento FIN. È
162 pertanto del tutto normale dal punto di vista del protocollo che uno dei due
163 capi chiuda la connessione, quando l'altro capo la lascia
164 aperta.\footnote{abbiamo incontrato questa situazione nei vari scenari critici
165 di \secref{sec:TCP_echo_critical}.}
167 È pertanto possibile avere una situazione in cui un capo della connessione non
168 avendo più nulla da scrivere, possa chiudere il socket, segnalando così
169 l'avvenuta terminazione della trasmissione (l'altro capo riceverà infatti un
170 end-of-file in lettura) mentre dall'altra parte si potrà proseguire la
171 trasmissione dei dati scrivendo sul socket che da quel lato è ancora aperto.
172 Questa è quella situazione in cui si dice che il socket è \textit{half
175 Il problema che si pone è che se la chiusura del socket è effettuata con la
176 funzione \func{close}, come spiegato in \secref{sec:TCP_func_close}, si perde
177 ogni possibilità di poter rileggere quanto l'altro capo può continuare a
178 scrivere. Per poter permettere allora
185 %%% TeX-master: "gapil"