Altro lavoro sul server echo, e sulle condizioni particolari
authorSimone Piccardi <piccardi@gnulinux.it>
Thu, 19 Jun 2003 11:43:13 +0000 (11:43 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Thu, 19 Jun 2003 11:43:13 +0000 (11:43 +0000)
elemtcp.tex
html/index.html
img/endianess.dia
socket.tex
sources/TCP_echod.c

index 585f605..cfc4c85 100644 (file)
@@ -1328,7 +1328,7 @@ Il primo passo (\texttt{\small 14--18}) 
 \func{socket} ritorna il descrittore che viene usato per identificare il
 socket in tutte le chiamate successive. Nel caso la chiamata fallisca si
 stampa un errore (\texttt{\small 16}) con la funzione \func{perror} e si esce
-(\texttt{\small 16}) con un codice di errore.
+(\texttt{\small 17}) con un codice di errore.
 
 Il passo seguente (\texttt{\small 19--27}) è quello di costruire un'apposita
 struttura \struct{sockaddr\_in} in cui sarà inserito l'indirizzo del server ed
@@ -2114,16 +2114,20 @@ la rete 
 gestire tutta una serie di situazioni critiche che non esistono per i processi
 locali.
 
-Come accennato in \secref{sec:TCP_func_accept} la funzione \func{accept}
-riporta tutti gli eventuali errori di rete pendenti su una connessione sul
-\textit{connected socket}; questo significa che, oltre al caso di interruzione
-da parte di un segnale, esistono altri errori non fatali che necessitano
-semplicemente la ripetizione della chiamata senza che si debba uscire dal
-programma. Un esempio possibile è quello mostrato in
-\figref{fig:TCP_early_abort}, in cui la connessione viene abortita dal client
-con l'invio di un segmento RST prima che sia stata chiamata la funzione
-\func{accept}.
-
+La prima situazione critica è quella della terminazione precoce, per via di un
+qualche errore di rete, della connessione effettuata da un client. Come
+accennato in \secref{sec:TCP_func_accept} la funzione \func{accept} riporta
+tutti gli eventuali errori di rete pendenti su una connessione sul
+\textit{connected socket}. 
+
+Questo significa che, oltre alla interruzione da parte di un segnale, che
+abbiamo trattato in \secref{sec:TCP_child_hand} nel caso particolare di
+\const{SIGCHLD}, si possono avere altri errori non fatali all'uscita di
+\func{accept}, che necessitano semplicemente la ripetizione della chiamata
+senza che si debba uscire dal programma. Uno scenario tipo è quello mostrato
+in \figref{fig:TCP_early_abort}, in cui la connessione viene abortita sul lato
+client con l'invio di un segmento RST, prima che nel server sia stata chiamata
+la funzione \func{accept}.
 
 \begin{figure}[htb]
   \centering
@@ -2132,6 +2136,30 @@ con l'invio di un segmento RST prima che sia stata chiamata la funzione
   \label{fig:TCP_early_abort}
 \end{figure}
 
+Benché questo non sia un fatto comune un evento simile può essere osservato
+con dei server molto occupati. In tal caso, in una struttura del server simile
+a quella del nostro esempio, in cui la gestione delle singole connessioni è
+demandata a processi figli, può accadere che il three way handshake venga
+completato e la relativa connessione abortita subito dopo, prima che il padre,
+per via del carico della macchina abbia fatto in tempo a rieseguire la
+chiamata \func{accept}. In questo caso si ha una situazione analoga a quella
+illustrata in \figref{fig:TCP_early_abort}, la connessione viene stabilita, ma
+subito dopo si ha una condizione 
+
+
+che, come nell'esempio in figura, ritornerebbe
+immediatamente con un errore relativo alla connessione abortita.
+
+
+Si tenga presente che questo tipo di terminazione non è riproducibile
+terminando il client prima della chiamata ad \func{accept}; in tal caso
+infatti il socket associato alla connessione viene semplicemente chiuso,
+attraverso la sequenza vista in \secref{sec:TCP_conn_term}, per cui la
+\func{accept} ritornerà senza errori, e si avrà semplicemente un end-of-file
+al primo accesso al socket.
+
+In questo caso 
+
 
 
 %%% Local Variables: 
index 6527164..f39abd8 100644 (file)
                attenzione particolare alle GNU libc, che sono la versione più
                usata delle librerie del C, senza dimenticare, ove note, di
                citare le differenze con possibili alternative come le libc5 o
-               le ulibc.
+               le uclibc.
            </p>
            <p>
                L'obiettivo resta comunque quello di riuscire a produrre una
              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>On Line</b> </font></A>, finalemente
+             face="sans-serif"> <b>online</b> </font></A>, finalmente
              all'altezza della versione stampabile.
            </p>
          </td>
index 2d88d94..8b309a8 100644 (file)
Binary files a/img/endianess.dia and b/img/endianess.dia differ
index 4adb5c7..3315352 100644 (file)
@@ -732,12 +732,11 @@ cos
 \label{sec:sock_addr_func}
 
 In questa sezione tratteremo delle varie funzioni usate per manipolare gli
-indirizzi, limitandoci però agli indirizzi internet.
-
-Come accennato gli indirizzi e i numeri di porta usati nella rete devono
-essere forniti in formato opportuno (il \textit{network order}). Per capire
-cosa significa tutto ciò occorre introdurre un concetto generale che tornerà
-utile anche in seguito.
+indirizzi, limitandoci però agli indirizzi internet.  Come accennato gli
+indirizzi e i numeri di porta usati nella rete devono essere forniti in
+formato opportuno (il \textit{network order}). Per capire cosa significa tutto
+ciò occorre introdurre un concetto generale che tornerà utile anche in
+seguito.
 
 
 \subsection{La \textit{endianess}\index{endianess}}
@@ -762,7 +761,7 @@ parte dal bit meno significativo 
 
 \begin{figure}[htb]
   \centering
-  \includegraphics[height=5cm]{img/endianess}
+  \includegraphics[height=3cm]{img/endianess}
   \caption{Schema della disposizione dei dati in memoria a seconda della
     \textit{endianess}\index{endianess}.}
   \label{fig:sock_endianess}
@@ -788,15 +787,11 @@ questi cambiamenti.
 Il problema connesso all'endianess\index{endianess} è che quando si passano
 dei dati da un tipo di architettura all'altra i dati vengono interpretati in
 maniera diversa, e ad esempio nel caso dell'intero a 16 bit ci si ritroverà
-con i due byte in cui è suddiviso scambiati di posto, e ne sarà quindi
-invertito l'ordine di lettura per cui, per riavere il valore originale,
-dovranno essere rovesciati.
-
-Per questo motivo si usano delle funzioni di conversione che servono a tener
-conto automaticamente della possibile differenza fra l'ordinamento usato sul
-computer e quello che viene usato nelle trasmissione sulla rete; queste
-funzioni sono \funcd{htonl}, \funcd{htons}, \funcd{ntohl} e \funcd{ntohs} ed i
-rispettivi prototipi sono:
+con i due byte in cui è suddiviso scambiati di posto.  Per questo motivo si
+usano delle funzioni di conversione che servono a tener conto automaticamente
+della possibile differenza fra l'ordinamento usato sul computer e quello che
+viene usato nelle trasmissione sulla rete; queste funzioni sono \funcd{htonl},
+\funcd{htons}, \funcd{ntohl} e \funcd{ntohs} ed i rispettivi prototipi sono:
 \begin{functions}
   \headdecl{netinet/in.h}
   \funcdecl{unsigned long int htonl(unsigned long int hostlong)} 
index 08d926f..35de97c 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: echod -h give all info
  *
- * $Id: TCP_echod.c,v 1.4 2003/06/18 21:19:24 piccardi Exp $ 
+ * $Id: TCP_echod.c,v 1.5 2003/06/19 11:43:13 piccardi Exp $ 
  *
  ****************************************************************/
 /* 
@@ -60,7 +60,9 @@ int main(int argc, char *argv[])
     int list_fd, conn_fd;
     int waiting;
     pid_t pid;
-    struct sockaddr_in serv_add;
+    struct sockaddr_in serv_add, cli_add;
+    socklen_t len;
+    char debug[MAXLINE], ipaddr[20];
     /*
      * Input section: decode parameters passed in the calling 
      * Use getopt function
@@ -142,12 +144,21 @@ int main(int argc, char *argv[])
     /* handle echo to client */
     while (1) {
        /* accept connection */
-       while (((conn_fd = accept(list_fd, NULL, NULL)) < 0
-              && (errno == EINTR)); 
+       while (((conn_fd = accept(list_fd, (struct sockaddr *)&cli_add, &len)
+               < 0) && (errno == EINTR)); 
        if ( conn_fd < 0) {
            PrintErr("accept error");
            exit(1);
        }
+       if (debugging) {
+           inet_ntop(AF_INET, &cli_add.sin_addr, ipaddr, sizeof(ipaddr));
+           snprintf(debug, MAXLINE, "Accepted connection form %s\n", ipaddr);
+           if (demonize) {
+               syslog(LOG_DEBUG, debug);
+           } else {
+               printf("%s", debug);
+           }
+       }
        /* fork to handle connection */
        if ( (pid = fork()) < 0 ){
            PrintErr("fork error");
@@ -190,7 +201,7 @@ void ServEcho(int sockfd) {
        if (debugging) {
            buffer[nread] = 0;
            snprintf(debug, MAXLINE+20, "Letti %d byte, %s", nread, buffer);
-           if (demonize) {          /* go daemon */
+           if (demonize) {          /* daemon mode */
                syslog(LOG_DEBUG, debug);
            } else {
                printf("%s", debug);
@@ -203,7 +214,7 @@ void ServEcho(int sockfd) {
  * routine to print error on stout or syslog
  */
 void PrintErr(char * error) {
-    if (demonize) {          /* go daemon */
+    if (demonize) {          /* daemon mode */
        syslog(LOG_ERR, error);
     } else {
        perror(error);