24c45d2cbf9d1aa707fec08f248fbb4e5703530e
[gapil.git] / tcpsockadv.tex
1  %% tcpsockadv.tex
2 %%
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
9 %% License".
10 %%
11 \chapter{Socket TCP avanzati}
12 \label{cha:TCP_advanced}
13
14 Esamineremo in questo capitolo le funzionalità più evolute della gestione dei
15 socket TCP. 
16
17
18
19 \section{Socket multiplexing}
20 \label{sec:TCP_sock_multiplexing}
21
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.
27
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.
35
36
37
38 \subsection{Il comportamento della funzione \func{select} con i socket.}
39 \label{sec:TCP_sock_select}
40
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.
46
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}.
54
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:
58 \begin{itemize*}
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
76   \const{SO\_ERROR}.
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.}
85 \end{itemize*}
86
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:
90 \begin{itemize*}
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}.
106 \end{itemize*}
107
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}.
113
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
119 scrittura.
120
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.}
135
136
137
138
139 \section{Le opzioni dei socket}
140 \label{sec:TCP_sock_options}
141
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.
146
147
148
149 \section{I dati \textit{out-of-band}}
150 \label{sec:TCP_outofband}
151
152 Una caratteristica speciale dei socket TCP è quella della presenza dei
153 cosiddetti dati \textit{out-of-band}
154
155
156
157 \subsection{La funzione \func{shutdown}}
158 \label{sec:TCP_shutdown}
159
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}.}
166
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
173   closed}.
174
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 
179
180
181
182
183 %%% Local Variables: 
184 %%% mode: latex
185 %%% TeX-master: "gapil"
186 %%% End: