\label{sec:file_multiplexing}
Per superare il problema di dover usare il \textit{polling}\index{polling} per
-controllare la possibilità di effettuare operazioni su un file aperto in
-modalità non bloccante, sia BSD che System V hanno introdotto delle nuove
-funzioni in grado di sospendere l'esecuzione di un processo in attesa che
-l'accesso diventi possibile. Il primo ad introdurre questa modalità di
-operazione, chiamata usualmente \textit{I/O multiplexing}, è stato
-BSD,\footnote{la funzione è apparsa in BSD4.2 e standardizzata in BSD4.4, ma è
- stata portata su tutti i sistemi che supportano i
- \textit{socket}\index{socket}, compreso le varianti di System V.} con la
-funzione \funcd{select}, il cui prototipo è:
+controllare la possibilità di effettuare operazioni su un gruppo di file
+aperti in modalità non bloccante, sia BSD che System V hanno introdotto delle
+nuove funzioni in grado di sospendere l'esecuzione di un processo fin quando
+l'accesso ad un dato insieme di file diventi possibile. Il primo ad
+introdurre questa modalità di operazione, chiamata usualmente \textit{I/O
+ multiplexing}, è stato BSD,\footnote{la funzione è apparsa in BSD4.2 e
+ standardizzata in BSD4.4, ma è stata portata su tutti i sistemi che
+ supportano i \textit{socket}\index{socket}, compreso le varianti di System
+ V.} con la funzione \funcd{select}, il cui prototipo è:
\begin{functions}
\headdecl{sys/time.h}
\headdecl{sys/types.h}
In genere un \textit{file descriptor set} può contenere fino ad un massimo di
\const{FD\_SETSIZE} file descriptor. Questo valore in origine corrispondeva
al limite per il numero massimo di file aperti\footnote{ad esempio in Linux,
- fino alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma
+ fino alla serie 2.0.x, c'era un limite di 256 file per processo.}, ma da
quando, come nelle versioni più recenti del kernel, non c'è più un limite
massimo, esso indica le dimensioni massime dei numeri usati nei \textit{file
- descriptor set}.
+ descriptor set}.\footnote{il suo valore, secondo lo standard POSIX
+ 1003.1-2001, è definito in \file{sys/select.h}, ed è pari a 1024.} Si tenga
+presente che i \textit{file descriptor set} devono sempre essere inizializzati
+con \macro{FD\_ZERO}; passare a \func{select} un valore non inizializzato può
+dar luogo a comportamenti non prevedibili.
La funzione richiede di specificare tre insiemi distinti di file descriptor;
il primo, \param{readfds}, verrà osservato per rilevare la disponibilità di
verificare l'esistenza di condizioni eccezionali (come i messaggi urgenti su
un \textit{socket}\index{socket}, vedi \secref{sec:xxx_urgent}).
-La funzione inoltre richiede anche di specificare, tramite l'argomento
-\param{n}, un valore massimo del numero dei file descriptor usati
-nell'insieme; si può usare il già citato \const{FD\_SETSIZE}, oppure il numero
-più alto dei file descriptor usati nei tre insiemi, aumentato di uno.
+Dato che in genere non si tengono mai sotto controllo fino a
+\const{FD\_SETSIZE} file contemporaneamente la funzione richiede di
+specificare qual'è il numero massimo dei file descriptor indicati nei tre
+insiemi precedenti. Questo viene fatto per efficienza, per evitare di passare
+e far controllare al kernel una quantità di memoria superiore a quella
+necessaria. Questo limite viene indicato tramite l'argomento \param{n}, che
+deve corrispondere al valore massimo aumentato di uno.\footnote{i file
+ descriptor infatti sono contati a partire da zero, ed il valore indica il
+ numero di quelli da tenere sotto controllo; dimenticarsi di aumentare di uno
+ il valore di \param{n} è un errore comune.}
Infine l'argomento \param{timeout}, specifica un tempo massimo di
-attesa\footnote{il tempo è valutato come \textit{elapsed time}.} prima che la
-funzione ritorni; se impostato a \val{NULL} la funzione attende
-indefinitamente. Si può specificare anche un tempo nullo (cioè una struttura
-\struct{timeval} con i campi impostati a zero), qualora si voglia
-semplicemente controllare lo stato corrente dei file descriptor.
+attesa\footnote{il tempo è valutato come \textit{clock time} (vedi
+ \secref{sec:sys_unix_time}).} prima che la funzione ritorni; se impostato a
+\val{NULL} la funzione attende indefinitamente. Si può specificare anche un
+tempo nullo (cioè una struttura \struct{timeval} con i campi impostati a
+zero), qualora si voglia semplicemente controllare lo stato corrente dei file
+descriptor.
La funzione restituisce il totale dei file descriptor pronti nei tre insiemi,
il valore zero indica sempre che si è raggiunto un timeout. Ciascuno dei tre
non vengono toccati.
In Linux \func{select} modifica anche il valore di \param{timeout},
-impostandolo al tempo restante; questo è utile quando la funzione viene
-interrotta da un segnale, in tal caso infatti si ha un errore di
-\errcode{EINTR}, ed occorre rilanciare la funzione; in questo modo non è
-necessario ricalcolare tutte le volte il tempo rimanente.\footnote{questo può
- causare problemi di portabilità sia quando si trasporta codice scritto su
- Linux che legge questo valore, sia quando si usano programmi scritti per
- altri sistemi che non dispongono di questa caratteristica e ricalcolano
- \param{timeout} tutte le volte. In genere la caratteristica è disponibile
- nei sistemi che derivano da System V e non disponibile per quelli che
- derivano da BSD.}
-
-Come accennato l'interfaccia di \func{select} è una estensione di BSD; anche
-System V ha introdotto una sua interfaccia per gestire l'\textit{I/O
- multiplexing}, basata sulla funzione \funcd{poll},\footnote{la funzione è
- prevista dallo standard XPG4, ed è stata introdotta in Linux come system
- call a partire dal kernel 2.1.23 e dalle \acr{libc} 5.4.28.} il cui
+impostandolo al tempo restante in caso di interruzione prematura; questo è
+utile quando la funzione viene interrotta da un segnale, in tal caso infatti
+si ha un errore di \errcode{EINTR}, ed occorre rilanciare la funzione; in
+questo modo non è necessario ricalcolare tutte le volte il tempo
+rimanente.\footnote{questo può causare problemi di portabilità sia quando si
+ trasporta codice scritto su Linux che legge questo valore, sia quando si
+ usano programmi scritti per altri sistemi che non dispongono di questa
+ caratteristica e ricalcolano \param{timeout} tutte le volte. In genere la
+ caratteristica è disponibile nei sistemi che derivano da System V e non
+ disponibile per quelli che derivano da BSD.}
+
+Come accennato l'interfaccia di \func{select} è una estensione creata nello
+sviluppo di BSD; anche System V ha introdotto una sua interfaccia per gestire
+l'\textit{I/O multiplexing}, basata sulla funzione \funcd{poll},\footnote{la
+ funzione è prevista dallo standard XPG4, ed è stata introdotta in Linux come
+ system call a partire dal kernel 2.1.23 e dalle \acr{libc} 5.4.28.} il cui
prototipo è:
\begin{prototype}{sys/poll.h}
{int poll(struct pollfd *ufds, unsigned int nfds, int timeout)}
-
-La funzione attente un cambiamento di stato per uno dei file descriptor
-specificati da \param{ufds}.
+
+ La funzione attende un cambiamento di stato per uno dei file descriptor
+ specificati da \param{ufds}.
\bodydesc{La funzione restituisce il numero di file descriptor con attività in
caso di successo, o 0 se c'è stato un timeout; in caso di errore viene
restituito -1 ed \var{errno} assumerà uno dei valori:
\begin{errlist}
\item[\errcode{EBADF}] Si è specificato un file descriptor sbagliato in uno
- degli insiemi.
+ degli insiemi.
\item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
\end{errlist}
ed inoltre \errval{EFAULT} e \errval{ENOMEM}.}
\const{POLLWRNORM}& 0x100 & È possibile la scrittura di dati normali. \\
\const{POLLWRBAND}& 0x200 & È possibile la scrittura di dati ad
alta priorità. \\
- \const{POLLMSG} & 0x400 & Estensione propria di Linux.\\
+ \const{POLLMSG} & 0x400 & Un segnale \const{SIGPOLL} è arrivato alla
+ cima dello stream.\\
\hline
\end{tabular}
\caption{Costanti per l'identificazione dei vari bit dei campi
diventa superabile disabilitando il segnale prima del test e riabilitandolo
poi grazie all'uso di \param{sigmask}.
+Dato che l'I/O multiplexing serve a risolvere il problema di dover attendere
+la disponibilità di accesso ad un insieme di file, esso viene utilizzato
+prevalentemente per programmi in cui l'accesso ad un file descriptor può
+essere bloccante. Abbiamo già accennato come questo non avvenga mai per i
+normali file su disco; l'uso più comune di queste funzioni infatti è nei
+server di rete, in cui esse vengono utilizzate per tenere sotto controllo vari
+socket; pertanto ritorneremo su di esse con maggiori dettagli e con qualche
+esempio in \secref{sec:TCP_sock_multiplexing}.
+
\subsection{L'I/O asincrono}
--- /dev/null
+%% tcpsockadv.tex
+%%
+%% Copyright (C) 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",
+%% 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".
+%%
+\chapter{Socket TCP avanzati}
+\label{cha:TCP_advanced}
+
+Esamineremo in questo capitolo le funzionalità più evolute della gestione dei
+socket TCP.
+
+
+
+\section{Socket multiplexing}
+\label{sec:TCP_sock_mutiplexing}
+
+Affronteremo in questa sezione l'utilizzo dei socket
+
+
+
+\section{Le opzioni dei socket}
+\label{sec:TCP_sock_options}
+
+Dato che la maggior parte delle opzioni dei socket sono relative ai socket
+TCP, ed hanno poi significato analogo quando usate con altri socket,
+tratteremo qui l'argomento in generale.
+
+
+
+\section{I dati \textit{out-of-band}}
+\label{sec:TCP_outofband}
+
+Una caratteristica speciale dei socket TCP è quella della presenza dei
+cosiddetti dati \textit{out-of-band}
+
+
+
+\subsection{La funzione \func{shutdown}}
+\label{sec:TCP_shutdown}
+
+Come spiegato in \secref{sec:TCP_conn_term} il procedimento di chiusura di un
+socket TCP prevede che da entrambe le parti venga emesso un segmento FIN. È
+pertanto del tutto normale dal punto di vista del protocollo che uno dei due
+capi chiuda la connessione, quando l'altro capo la lascia
+aperta.\footnote{abbiamo incontrato questa situazione nei vari scenari critici
+ di \secref{sec:TCP_echo_critical}.}
+
+È pertanto possibile avere una situazione in cui un capo della connessione non
+avendo più nulla da scrivere, possa chiudere il socket, segnalando così
+l'avvenuta terminazione della trasmissione (l'altro capo riceverà infatti un
+end-of-file in lettura) mentre dall'altra parte si potrà proseguire la
+trasmissione dei dati scrivendo sul socket che da quel lato è ancora aperto.
+Questa è quella situazione in cui si dice che il socket è \textit{half
+ closed}.
+
+Il problema che si pone è che se la chiusura del socket è effettuata con la
+funzione \func{close}, come spiegato in \secref{sec:TCP_func_close}, si perde
+ogni possibilità di poter rileggere quanto l'altro capo può continuare a
+scrivere. Per poter permettere allora
+
+
+
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: