Messi alcuni riferimenti giusti all'urgent data e scritta la versione di
authorSimone Piccardi <piccardi@gnulinux.it>
Sat, 18 Oct 2003 16:30:23 +0000 (16:30 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sat, 18 Oct 2003 16:30:23 +0000 (16:30 +0000)
client che usa l'I/O multiplexing

fileadv.tex
html/gapil.html
signal.tex
sources/TCP_echo.c
sources/TCP_echo_second.c [new file with mode: 0644]
sources/macros.h
tcpsock.tex
tcpsockadv.tex

index 445d9c73fd613ef378ab181d1ed7924cc6d79a0e..fb516a3179faf40307aa38ef7400eef1db4df549 100644 (file)
@@ -149,7 +149,7 @@ il primo, \param{readfds}, verr
 effettuare una lettura, il secondo, \param{writefds}, per verificare la
 possibilità effettuare una scrittura ed il terzo, \param{exceptfds}, per
 verificare l'esistenza di condizioni eccezionali (come i messaggi urgenti su
 effettuare una lettura, il secondo, \param{writefds}, per verificare la
 possibilità effettuare una scrittura ed il terzo, \param{exceptfds}, per
 verificare l'esistenza di condizioni eccezionali (come i messaggi urgenti su
-un \textit{socket}\index{socket}, vedi \secref{sec:xxx_urgent}).
+un \textit{socket}\index{socket}, vedi \secref{sec:TCP_urgent_data}).
 
 Dato che in genere non si tengono mai sotto controllo fino a
 \const{FD\_SETSIZE} file contemporaneamente la funzione richiede di
 
 Dato che in genere non si tengono mai sotto controllo fino a
 \const{FD\_SETSIZE} file contemporaneamente la funzione richiede di
index 7024ee80d5b780f94bc9ec9adb2f8e06c5484f30..133db1edc883debac958cbb06b5a31b1be47c439 100644 (file)
              </font></a>. Grazie all'opera di Mirko Maischberger abbiamo
              anche una bellissima versione HTML, accessibile nella sezione <a
              href="http://www.lilik.it/~mirko/gapil/gapil.html"> <font
              </font></a>. Grazie all'opera di Mirko Maischberger abbiamo
              anche una bellissima versione HTML, accessibile nella sezione <a
              href="http://www.lilik.it/~mirko/gapil/gapil.html"> <font
-             face="sans-serif"> <b>online</b> </font></a>, finalmente
+             face="sans-serif"> <b>online</b></font></a>, finalmente
              all'altezza della versione stampabile.
          </td>
        </tr>
              all'altezza della versione stampabile.
          </td>
        </tr>
index 296d579291d78b5b08a20f98d4f45fcd56a6360e..20c0f90203da9e33ca9c604a95c530dfb30fdd2a 100644 (file)
@@ -584,8 +584,8 @@ L'azione predefinita 
   questo può essere usato anche per i file, posto che la \func{fcntl} abbia
   avuto successo.
 \item[\const{SIGURG}] Questo segnale è inviato quando arrivano dei dati
   questo può essere usato anche per i file, posto che la \func{fcntl} abbia
   avuto successo.
 \item[\const{SIGURG}] Questo segnale è inviato quando arrivano dei dati
-  urgenti o \textit{out of band} su di un socket\index{socket}; per maggiori
-  dettagli al proposito si veda \secref{sec:xxx_urgent_data}.
+  urgenti o \textit{out-of-band} su di un socket\index{socket}; per maggiori
+  dettagli al proposito si veda \secref{sec:TCP_urgent_data}.
 \item[\const{SIGPOLL}] Questo segnale è equivalente a \const{SIGIO}, è
   definito solo per compatibilità con i sistemi System V.
 \end{basedescript}
 \item[\const{SIGPOLL}] Questo segnale è equivalente a \const{SIGIO}, è
   definito solo per compatibilità con i sistemi System V.
 \end{basedescript}
index 86b78c2762a1806840bb757680d6ee0c49d7b317..c8c5c1ac97910381607852c971c5ce1c3203d11c 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: echo -h give all info's
  *
  *
  * Usage: echo -h give all info's
  *
- * $Id: TCP_echo.c,v 1.8 2003/08/17 23:03:44 piccardi Exp $
+ * $Id: TCP_echo.c,v 1.9 2003/10/18 16:30:23 piccardi Exp $
  *
  ****************************************************************/
 /* 
  *
  ****************************************************************/
 /* 
@@ -40,6 +40,8 @@
 #include <errno.h>      /* include error codes */
 #include <string.h>     /* include erroro strings definitions */
 
 #include <errno.h>      /* include error codes */
 #include <string.h>     /* include erroro strings definitions */
 
+#include "macros.h"
+
 #define MAXLINE 256
 void usage(void);
 void ClientEcho(FILE * filein, int socket);
 #define MAXLINE 256
 void usage(void);
 void ClientEcho(FILE * filein, int socket);
@@ -138,26 +140,41 @@ void ClientEcho(FILE * filein, int socket)
 {
     char sendbuff[MAXLINE+1], recvbuff[MAXLINE+1];
     int nread, nwrite; 
 {
     char sendbuff[MAXLINE+1], recvbuff[MAXLINE+1];
     int nread, nwrite; 
-    while (fgets(sendbuff, MAXLINE, filein) != NULL) {
-       nwrite = FullWrite(socket, sendbuff, strlen(sendbuff)); 
-       if (nwrite < 0) {
-           printf("Errore in scrittura: %s", strerror(errno));
-           return;
-       }
-        nread = read(socket, recvbuff, strlen(sendbuff));
-       if (nread < 0) {
-           printf("Errore in lettura: %s\n", strerror(errno));
-           return;
-       }
-       if (nread == 0) {
-           printf("EOF sul socket\n");
-           return;
+    int maxfd;
+    fd_set fset;
+    /* initialize file descriptor set */
+    FD_ZERO(&fset);
+    maxfd = max(fileno(stdin), socket) + 1;
+    while (1) {
+       FD_SET(socket, &fset);        /* set for the socket */
+       FD_SET(fileno(stdin), &fset); /* set for the standard input */
+       select(maxfd, &fset, NULL, NULL, NULL); /* wait for read ready */
+       if (FD_ISSET(fileno(stdin), &fset)) {   /* if ready on stdin */
+           if (fgets(sendbuff, MAXLINE, filein) == NULL) { /* if no input */
+               return;               /* we stopped client */
+           } else {                  /* else we have to write to socket */
+               nwrite = FullWrite(socket, sendbuff, strlen(sendbuff)); 
+               if (nwrite < 0) {     /* on error stop */
+                   printf("Errore in scrittura: %s", strerror(errno));
+                   return;
+               }
+           }
        }
        }
-       recvbuff[nread] = 0;
-       if (fputs(recvbuff, stdout) == EOF) {
-           perror("Errore in scrittura su terminale");
-           return;
+       if (FD_ISSET(socket, &fset)) { /* if ready on socket */ 
+           nread = read(socket, recvbuff, strlen(sendbuff)); /* do read */
+           if (nread < 0) {  /* error condition, stop client */
+               printf("Errore in lettura: %s\n", strerror(errno));
+               return;
+           }
+           if (nread == 0) { /* server closed connection, stop */
+               printf("EOF sul socket\n");
+               return;
+           }
+           recvbuff[nread] = 0;   /* else read is ok, write on stdout */
+           if (fputs(recvbuff, stdout) == EOF) {
+               perror("Errore in scrittura su terminale");
+               return;
+           }
        }
     }
        }
     }
-    return;
 }
 }
diff --git a/sources/TCP_echo_second.c b/sources/TCP_echo_second.c
new file mode 100644 (file)
index 0000000..fcf5a4f
--- /dev/null
@@ -0,0 +1,163 @@
+/* TCP_echo.c
+ * 
+ * Copyright (C) 2001-2003 Simone Piccardi
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/****************************************************************
+ *
+ * Program TCP_echo.c
+ * Simple TCP client for echo service (port 7)
+ *
+ * Author: Simone Piccardi
+ * Jun. 2001
+ *
+ * Usage: echo -h give all info's
+ *
+ * $Id: TCP_echo_second.c,v 1.1 2003/10/18 16:30:23 piccardi Exp $
+ *
+ ****************************************************************/
+/* 
+ * Include needed headers
+ */
+#include <sys/types.h>   /* predefined types */
+#include <unistd.h>      /* include unix standard library */
+#include <arpa/inet.h>   /* IP addresses conversion utiliites */
+#include <sys/socket.h>  /* socket library */
+#include <stdio.h>      /* include standard I/O library */
+#include <errno.h>      /* include error codes */
+#include <string.h>     /* include erroro strings definitions */
+
+#define MAXLINE 256
+void usage(void);
+void ClientEcho(FILE * filein, int socket);
+void SigTERM_hand(int sig);
+
+/* Program begin */
+int main(int argc, char *argv[])
+{
+/* 
+ * Variables definition  
+ */
+    int sock, i;
+    int reset = 0;
+    struct sockaddr_in serv_add;
+    struct linger ling;
+    /*
+     * Input section: decode parameters passed in the calling 
+     * Use getopt function
+     */
+    opterr = 0;         /* don't want writing to stderr */
+    while ( (i = getopt(argc, argv, "hr")) != -1) {
+       switch (i) {
+       /* 
+        * Handling options 
+        */ 
+       case 'h':  
+           printf("Wrong -h option use\n");
+           usage();
+           return(1);
+           break;
+       case 'r':
+           reset = 1;
+           break;
+       case '?':   /* unrecognized options */
+           printf("Unrecognized options -%c\n",optopt);
+           usage();
+       default:    /* should not reached */
+           usage();
+       }
+    }
+    /* ***********************************************************
+     * 
+     *          Options processing completed
+     *
+     *               Main code beginning
+     * 
+     * ***********************************************************/
+    /* create socket */
+    if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+       perror("Socket creation error");
+       return 1;
+    }
+    /* initialize address */
+    memset((void *) &serv_add, 0, sizeof(serv_add)); /* clear server address */
+    serv_add.sin_family = AF_INET;                   /* address type is INET */
+    serv_add.sin_port = htons(7);                    /* echo port is 7 */
+    /* build address using inet_pton */
+    if ( (inet_pton(AF_INET, argv[optind], &serv_add.sin_addr)) <= 0) {
+       perror("Address creation error");
+       return 1;
+    }
+    /* extablish connection */
+    if (connect(sock, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+       perror("Connection error");
+       return 1;
+    }
+    /* check if resetting on close is required */
+    if (reset) {
+       printf("Setting reset on close \n");
+       ling.l_onoff = 1;
+       ling.l_linger = 0;      
+       if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling))) {
+           perror("Cannot set linger");
+           exit(1);
+       }
+    }
+    /* do read/write operations */
+    ClientEcho(stdin, sock);
+    /* normal exit */
+    return 0;
+}
+/*
+ * routine to print usage info and exit 
+ */
+void usage(void) {
+    printf("Take daytime from a remote host \n");
+    printf("Usage:\n");
+    printf("  daytime [-h] [-v] [host in dotted decimal form] \n");
+//    printf("  -v        set verbosity on\n");
+    printf("  -r          require reset on closing\n");
+    printf("  -h          print this help\n");
+    exit(1);
+}
+
+void ClientEcho(FILE * filein, int socket) 
+{
+    char sendbuff[MAXLINE+1], recvbuff[MAXLINE+1];
+    int nread, nwrite; 
+    while (fgets(sendbuff, MAXLINE, filein) != NULL) {
+       nwrite = FullWrite(socket, sendbuff, strlen(sendbuff)); 
+       if (nwrite < 0) {
+           printf("Errore in scrittura: %s", strerror(errno));
+           return;
+       }
+        nread = read(socket, recvbuff, strlen(sendbuff));
+       if (nread < 0) {
+           printf("Errore in lettura: %s\n", strerror(errno));
+           return;
+       }
+       if (nread == 0) {
+           printf("EOF sul socket\n");
+           return;
+       }
+       recvbuff[nread] = 0;
+       if (fputs(recvbuff, stdout) == EOF) {
+           perror("Errore in scrittura su terminale");
+           return;
+       }
+    }
+    return;
+}
index 9784c7aa3c2b5fa91fb67ec4480a3e45d309cbef..1c978ed4d9d73703924171c95bc73b91ff4e1dc4 100644 (file)
         (v>>24) | ((v>>8)&0xFF00) | (v<<24) | ((v<<8)&0xFF0000); } )
 #define BE16_TO_LE16(val) ({typeof (val) v= (val);  (v>>8) | (v<<8); } )
 /* 
         (v>>24) | ((v>>8)&0xFF00) | (v<<24) | ((v<<8)&0xFF0000); } )
 #define BE16_TO_LE16(val) ({typeof (val) v= (val);  (v>>8) | (v<<8); } )
 /* 
- * Define a protected, right typed, no side effects macro for min
+ * Define a protected, right typed, no side effects macro for min and max
  */
 #define min(x, y) ({typeof (x) x_ = (x); typeof (y) y_ = (y); \
                   x_ < y_ ? x_ : y_;}) 
  */
 #define min(x, y) ({typeof (x) x_ = (x); typeof (y) y_ = (y); \
                   x_ < y_ ? x_ : y_;}) 
+#define max(x, y) ({typeof (x) x_ = (x); typeof (y) y_ = (y); \
+                  x_ > y_ ? x_ : y_;}) 
 /* 
  * debugging print definition
  */
 /* 
  * debugging print definition
  */
index ae53fd0d1dc7585b0451710636820d80484c0772..2318fb017cfb0a20107ec3947a534efcbee2b032 100644 (file)
@@ -8,7 +8,7 @@
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
-\chapter{Socket TCP}
+\chapter{Socket TCP elementari}
 \label{cha:TCP_socket}
 
 In questo capitolo iniziamo ad approfondire la conoscenza dei socket TCP,
 \label{cha:TCP_socket}
 
 In questo capitolo iniziamo ad approfondire la conoscenza dei socket TCP,
@@ -2430,7 +2430,7 @@ la nuova versione della funzione in \figref{fig:TCP_ClientEcho_second}.
   \end{minipage} 
   \normalsize
   \caption{La sezione nel codice della seconda versione della funzione
   \end{minipage} 
   \normalsize
   \caption{La sezione nel codice della seconda versione della funzione
-    \func{CleintEcho} usata dal client per il servizio \textit{echo}
+    \func{ClientEcho} usata dal client per il servizio \textit{echo}
     modificata per tener conto degli eventuali errori.}
   \label{fig:TCP_ClientEcho_second}
 \end{figure}
     modificata per tener conto degli eventuali errori.}
   \label{fig:TCP_ClientEcho_second}
 \end{figure}
index 24c45d2cbf9d1aa707fec08f248fbb4e5703530e..44986525fc3141b95422a22548adb4ede34b939a 100644 (file)
 \label{cha:TCP_advanced}
 
 Esamineremo in questo capitolo le funzionalità più evolute della gestione dei
 \label{cha:TCP_advanced}
 
 Esamineremo in questo capitolo le funzionalità più evolute della gestione dei
-socket TCP. 
+socket TCP, come l'uso del I/O multiplexing (trattato in
+\secref{sec:file_multiplexing}) con i socket, l'uso delle opzioni dei socket e
+la gestione dei dati urgenti e \textit{out-of-band}.
 
 
 
 
 
 
-\section{Socket multiplexing}
+\section{Socket I/O multiplexing}
 \label{sec:TCP_sock_multiplexing}
 
 Affronteremo in questa sezione l'utilizzo dell'I/O multiplexing, affrontato in
 \secref{sec:file_multiplexing}, nell'ambito delle applicazioni di rete. Già in
 \label{sec:TCP_sock_multiplexing}
 
 Affronteremo in questa sezione l'utilizzo dell'I/O multiplexing, affrontato in
 \secref{sec:file_multiplexing}, nell'ambito delle applicazioni di rete. Già in
-\ref{sec:TCP_server_crash} era emerso il problema relativo al client del
+\secref{sec:TCP_server_crash} era emerso il problema relativo al client del
 servizio echo che non era in grado di accorgersi della terminazione precoce
 servizio echo che non era in grado di accorgersi della terminazione precoce
-del server essendo bloccato nella lettura dei dati immessi da tastiera.
+del server, essendo bloccato nella lettura dei dati immessi da tastiera.
 
 Abbiamo visto in \secref{sec:file_multiplexing} quali sono le funzionalità del
 sistema che ci permettono di tenere sotto controllo più file descriptor in
 contemporanea; in quella occasione non abbiamo fatto esempi, in quanto quando
 
 Abbiamo visto in \secref{sec:file_multiplexing} quali sono le funzionalità del
 sistema che ci permettono di tenere sotto controllo più file descriptor in
 contemporanea; in quella occasione non abbiamo fatto esempi, in quanto quando
-si tratta con file normali questa tipologia di I/O non viene usata, è invece
-un caso tipico delle applicazioni di rete quello di dover gestire varie
-connessioni da cui possono arrivare dati comuni in maniera asincrona, per cui
-riprenderemo l'argomento in questa sezione.
-
+si tratta con file normali questa tipologia di I/O normalmente non viene
+usata, è invece un caso tipico delle applicazioni di rete quello di dover
+gestire varie connessioni da cui possono arrivare dati comuni in maniera
+asincrona, per cui riprenderemo l'argomento in questa sezione.
 
 
 \subsection{Il comportamento della funzione \func{select} con i socket.}
 \label{sec:TCP_sock_select}
 
 Iniziamo con la prima delle funzioni usate per l'I/O multiplexing,
 
 
 \subsection{Il comportamento della funzione \func{select} con i socket.}
 \label{sec:TCP_sock_select}
 
 Iniziamo con la prima delle funzioni usate per l'I/O multiplexing,
-\func{select}, il suo funzionamento è già stato descritto in dettaglio in
+\func{select}; il suo funzionamento è già stato descritto in dettaglio in
 \secref{sec:file_multiplexing} e non staremo a ripetere quanto detto lì; 
 sappiamo che la funzione ritorna quando uno o più dei file descriptor messi
 sotto controllo è pronto per la relativa operazione.
 
 In quell'occasione non abbiamo però definito cosa si intende per pronto,
 infatti per dei normali file, o anche per delle pipe, la condizione di essere
 \secref{sec:file_multiplexing} e non staremo a ripetere quanto detto lì; 
 sappiamo che la funzione ritorna quando uno o più dei file descriptor messi
 sotto controllo è pronto per la relativa operazione.
 
 In quell'occasione non abbiamo però definito cosa si intende per pronto,
 infatti per dei normali file, o anche per delle pipe, la condizione di essere
-pronti per la lettura o la scrittura è ovvia, lo è un po' meno di meno nel
-caso dei socket, visto che intervengono tutte le possibili condizioni dovute
-alla rete. Occorre allora specificare quali sono le condizioni in cui un
-socket risulta \textsl{pronto} quando viene passato come membro di uno dei tre
-\textit{file descriptor set} usati da \func{select}.
+pronti per la lettura o la scrittura è ovvia; invece lo è molto meno nel caso
+dei socket, visto che possono intervenire tutte una serie di possibili
+condizioni di errore dovute alla rete. Occorre allora specificare chiaramente
+quali sono le condizioni per cui un socket risulta essere ``\textsl{pronto}''
+quando viene passato come membro di uno dei tre \textit{file descriptor set}
+usati da \func{select}.
 
 Le condizioni che fanno si che la funzione \func{select} ritorni segnalando
 che un socket (che sarà riportato nel primo insieme di file descriptor) è
 
 Le condizioni che fanno si che la funzione \func{select} ritorni segnalando
 che un socket (che sarà riportato nel primo insieme di file descriptor) è
@@ -80,8 +82,8 @@ pronto per la lettura sono le seguenti:
     \secref{sec:TCP_conn_early_abort} una connessione può essere abortita
     dalla ricezione di un segmento RST una volta che è stata completata,
     allora se questo avviene dopo che \func{select} è ritornata, ma prima
     \secref{sec:TCP_conn_early_abort} una connessione può essere abortita
     dalla ricezione di un segmento RST una volta che è stata completata,
     allora se questo avviene dopo che \func{select} è ritornata, ma prima
-    della chiamata ad \func{accept} quest'ultima, in assenza di altre
-    connessiioni, potrà bloccarsi.}
+    della chiamata ad \func{accept}, quest'ultima, in assenza di altre
+    connessioni, potrà bloccarsi.}
 \end{itemize*}
 
 Le condizioni che fanno si che la funzione \func{select} ritorni segnalando
 \end{itemize*}
 
 Le condizioni che fanno si che la funzione \func{select} ritorni segnalando
@@ -109,14 +111,14 @@ Infine c'
 che un socket (che sarà riportato nel terzo insieme di file descriptor) ha una
 condizione di eccezione pendente, e cioè la ricezione sul socket di dati
 \textsl{fuori banda} (o \textit{out-of-band}), una caratteristica specifica
 che un socket (che sarà riportato nel terzo insieme di file descriptor) ha una
 condizione di eccezione pendente, e cioè la ricezione sul socket di dati
 \textsl{fuori banda} (o \textit{out-of-band}), una caratteristica specifica
-dei socket TCP su cui torneremo in \secref{sec:TCP_outofband}.
+dei socket TCP su cui torneremo in \secref{sec:TCP_urgent_data}.
 
 Si noti come nel caso della lettura \func{select} si applichi anche ad
 
 Si noti come nel caso della lettura \func{select} si applichi anche ad
-operazioni che non hanno nulla a che fare con l'I/O come il riconoscimento
-della presenza di connessioni pronte, in modo da consentire l'utilizzo di
-\func{accept} in modalità non bloccante. Si noti infine come in caso di errore
-un socket venga sempre riportato come pronto sia per la lettura che per la
-scrittura.
+operazioni che non hanno nulla a che fare con l'I/O di dati come il
+riconoscimento della presenza di connessioni pronte, in modo da consentire
+anche l'utilizzo di \func{accept} in modalità non bloccante. Si noti infine
+come in caso di errore un socket venga sempre riportato come pronto sia per la
+lettura che per la scrittura.
 
 Lo scopo dei due valori di soglia per i buffer di ricezione e di invio è
 quello di consentire maggiore flessibilità nell'uso di \func{select} da parte
 
 Lo scopo dei due valori di soglia per i buffer di ricezione e di invio è
 quello di consentire maggiore flessibilità nell'uso di \func{select} da parte
@@ -129,11 +131,95 @@ quando c'
   sempre quanti dati invia, mentre non è detto possa conoscere la quantità di
   dati in ricezione; per cui, nella situazione in cui si conosce almeno un
   valore minimo, per evitare la penalizzazione dovuta alla ripetizione delle
   sempre quanti dati invia, mentre non è detto possa conoscere la quantità di
   dati in ricezione; per cui, nella situazione in cui si conosce almeno un
   valore minimo, per evitare la penalizzazione dovuta alla ripetizione delle
-  operazioni di lettura quando per accumulare dati sufficienti, si può
-  lasciare al kernel il compito di impostare un minimo al di sotto del quale
-  il file descriptor, pur avendo disponibili dei dati, non viene letto.}
-
-
+  operazioni di lettura per accumulare dati sufficienti, si può lasciare al
+  kernel il compito di impostare un minimo al di sotto del quale il file
+  descriptor, pur avendo disponibili dei dati, non viene dato per pronto in
+  lettura.}
+
+
+
+\subsection{Un esempio di I/O multiplexing}
+\label{sec:TCP_multiplex_example}
+
+Abbiamo incontrato la problematica tipica che conduce all'uso dell'I/O
+multiplexing nella nostra analisi degli errori in
+\secref{sec:TCP_conn_early_abort}, quando il nostro client non era in grado di
+rendersi conto di errori sulla connessione essendo impegnato nella attesa di
+dati in ingresso dallo standard input.
+
+In questo caso il problema è quello di dover tenere sotto controllo due
+diversi file descriptor, lo standard input, da cui viene letto il testo che
+vogliamo inviare al server, e il socket connesso con il server su cui detto
+testo sarà scritto e dal quale poi si vorrà ricevere la risposta. L'uso
+dell'I/O multiplexing consente di tenere sotto controllo entrambi, senza
+restare bloccati.
+
+Nel nostro caso quello che ci interessa è non essere bloccati in lettura sullo
+standard input in caso di errori sulla connessione o chiusura della stessa da
+parte del server. Entrambi questi casi possono essere rilevati usando
+\func{select}, per quanto detto in \secref{sec:TCP_sock_select}, mettendo
+sotto osservazione i file descriptor per la condizione di essere pronti in
+lettura: sia infatti che si ricevano dati, che la connessione sia chiusa
+regolarmente (con la ricezione di un segmento FIN) che si riceva una
+condizione di errore (con un segmento RST) il socket connesso sarà pronto in
+lettura (nell'ultimo caso anche in scrittura, ma questo non è necessario ai
+nostri scopi).
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15.6cm}
+    \includecodesample{listati/ClientEcho_third.c}
+  \end{minipage} 
+  \normalsize
+  \caption{La sezione nel codice della terza versione della funzione
+    \func{ClientEcho} usata dal client per il servizio \textit{echo}
+    modificata per l'uso di \func{select}.}
+  \label{fig:TCP_ClientEcho_third}
+\end{figure}
+
+Riprendiamo allora il codice del client, modificandolo per l'uso di
+\func{select}. Quello che dobbiamo modificare è la funzione \func{ClientEcho}
+di \figref{fig:TCP_ClientEcho_second}, dato che tutto il resto, che riguarda
+le modalità in cui viene stabilita la connessione con il server, resta
+assolutamente identico. La nostra nuova versione di \func{ClientEcho}, la
+terza della serie, è riportata in \figref{fig:TCP_ClientEcho_third}.
+
+In questo caso la funzione comincia (\texttt{\small 8--9}) con la
+cancellazione del file descriptor set \var{fset} e del valore \var{maxfd} da
+passare a \func{select} come massimo per il numero dei file descriptor. Per
+quest'ultimo si usa la macro \code{max} definita nel nostro file
+\file{macro.h} che raccoglie una collezione di macro di preprocessore di varia
+utilità.
+
+La funzione prosegue poi (\texttt{\small 10--41}) con il ciclo principale, che
+viene ripetuto indefinitamente. Per ogni ciclo si reinizializza
+(\texttt{\small 11--12}) il file descriptor set, impostando i valori per il
+file descriptor associato al socket \var{socket} e per lo standard input (il
+cui valore si recupera con la funzione \func{fileno}). Questo è necessario in
+quanto la successiva (\texttt{\small 13}) chiamata a \func{select} comporta
+una modifica dei due bit relativi, che quindi devono essere reimpostati.
+
+Si noti come la chiamata a \func{select} venga eseguita usando come primo
+argomento il valore di \var{maxfd}, precedentemente calcolato, passando poi il
+solo file descriptor set per il controllo dell'attività in lettura, gli altri
+argomenti sono tutti passati come puntatori nulli non interessando né il
+controllo delle altre attività, né l'impostazione di un valore di timeout.
+
+Al ritorno di \func{select} si provvede a controllare quale dei file
+descriptor presneta attività, si comincia (\texttt{\small 14--24}) con il file
+descriptor associato allo standard input. In caso di attività (quando cioè
+\macro{FD_ISSET} ritorna una valore diverso da zero) si esegue (\texttt{\small
+  15}) una \func{fgets} per leggere gli eventuali dati presenti; se non ve ne
+sono (e la funzione restituisce pertanto un puntatore nullo) si ritorna
+immediatamente (\texttt{\small 16}) dato che questo significa che si è chiuso
+lo standard input; altrimenti (\texttt{\small 18--22}) si scrivono i dati sul
+socket, uscendo immediatamente in caso di errore di scrittura.
+
+Controllato lo standard input si passa a controllare (\texttt{\small 25--40})
+il socket connesso, in caso di attività si esegue (\texttt{\small 26}) subito
+una \func{read} di cui si controlla il valore di ritorno; se questo è negativo
+(\texttt{\small 27--30}) si è avuto un errore e pertanto si esce
+immediatamente segnalandolo, se è nullo (\texttt{\small 31--34}) 
 
 
 \section{Le opzioni dei socket}
 
 
 \section{Le opzioni dei socket}
@@ -141,13 +227,13 @@ quando c'
 
 Dato che la maggior parte delle opzioni dei socket sono relative ai socket
 TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
 
 Dato che la maggior parte delle opzioni dei socket sono relative ai socket
 TCP, ed hanno poi significato analogo quando usate con altri socket, abbiamo
-preferito trattare l'argomento in generale in questa sezione piuttosto che
-nel capitolo dedicato alla trattazione generica dei socket.
+preferito trattare l'argomento in generale in questa sezione piuttosto che nel
+capitolo dedicato alla trattazione generica dei socket.
 
 
 
 \section{I dati \textit{out-of-band}}
 
 
 
 \section{I dati \textit{out-of-band}}
-\label{sec:TCP_outofband}
+\label{sec:TCP_urgent_data}
 
 Una caratteristica speciale dei socket TCP è quella della presenza dei
 cosiddetti dati \textit{out-of-band}
 
 Una caratteristica speciale dei socket TCP è quella della presenza dei
 cosiddetti dati \textit{out-of-band}