Aggiunte note per le funzioni classiche dei socket per ricordarne il loro
authorSimone Piccardi <piccardi@gnulinux.it>
Thu, 25 Dec 2003 17:31:09 +0000 (17:31 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Thu, 25 Dec 2003 17:31:09 +0000 (17:31 +0000)
suo generico, corretti i listati dei server che usano accept, per dare un
input il corretto valore della lunghezza della struttura degli indirizzi,
risistemata la suddivisione in parti (con la terza parte per le appendici),
inserito lo scheletro iniziale di un server echo basato su select.

13 files changed:
gapil.tex
intro.tex
listati/TCP_cunc_daytimed.c
listati/TCP_echod_first.c
listati/TCP_echod_second.c
network.tex
sources/Makefile
sources/TCP_cunc_daytimed.c
sources/TCP_echod.c
sources/TCP_echod_first.c
sources/TCP_echod_second.c
sources/select_echod.c [new file with mode: 0644]
tcpsock.tex

index 62f70cb7d0eb2b4734b0375c7f74cb228ffe82a2..761d1d9f8b14ccf4b40eaa8ebcfeb7b79b6b5f6d 100644 (file)
--- a/gapil.tex
+++ b/gapil.tex
 % distance from margins for boxedminipage
 %\fboxsep=6pt
 
 % distance from margins for boxedminipage
 %\fboxsep=6pt
 
-
+\part{Programmazione di sistema}
+\label{part:progr-di-sist}
 \include{intro}
 \include{process}
 \include{prochand}
 \include{intro}
 \include{process}
 \include{prochand}
 \include{session}
 \include{fileadv}
 \include{ipc}
 \include{session}
 \include{fileadv}
 \include{ipc}
+\part{Programmazione di rete}
+\label{part:progr-di-rete}
 \include{network}
 \include{socket}
 \include{tcpsock}
 \include{tcpsockadv}
 \appendix
 \include{network}
 \include{socket}
 \include{tcpsock}
 \include{tcpsockadv}
 \appendix
+\part{Appendici}
+\label{part:appendici}
 \include{netlayer}
 \include{trasplayer}
 \include{errors}
 \include{netlayer}
 \include{trasplayer}
 \include{errors}
index 89eb59c664d3702e7a0402a9c44e59f757d40878..a7355de72c958bbe9f04a8b7f78b47dba5a6d0bc 100644 (file)
--- a/intro.tex
+++ b/intro.tex
@@ -8,10 +8,6 @@
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
-\part{Programmazione di sistema}
-\label{part:progr-di-sist}
-
-
 \chapter{L'architettura del sistema}
 \label{cha:intro_unix}
 
 \chapter{L'architettura del sistema}
 \label{cha:intro_unix}
 
index 9af8cc772ba2c0a2122fa2672f21b18305bb025f..17160be766b2c94508568ecd84d881127b50cf01 100644 (file)
@@ -18,6 +18,7 @@ int main(int argc, char *argv[])
      ...
     /* write daytime to client */
     while (1) {
      ...
     /* write daytime to client */
     while (1) {
+       len = sizeof(client);
         if ( (conn_fd = accept(list_fd, (struct sockaddr *)&client, &len)) 
              <0 ) {
             perror("accept error");
         if ( (conn_fd = accept(list_fd, (struct sockaddr *)&client, &len)) 
              <0 ) {
             perror("accept error");
index 81085a7b5f59f831291723a6561475e6aaf624f5..0da60a6eb584af77e7ef602a1427baa39e1a9d50 100644 (file)
@@ -40,6 +40,7 @@ int main(int argc, char *argv[])
        exit(1);
     }
     while (1) {                          /* handle echo to client */
        exit(1);
     }
     while (1) {                          /* handle echo to client */
+       len = sizeof(cli_add);
        if ( (conn_fd = accept(list_fd, NULL, NULL)) < 0) { 
            PrintErr("accept error");
            exit(1);
        if ( (conn_fd = accept(list_fd, NULL, NULL)) < 0) { 
            PrintErr("accept error");
            exit(1);
index 78557afdb04fd9f9a16e3a9fb406d59b3ac9f1f4..26f09871052943903c1cebe9246d71a6e6c2d2cf 100644 (file)
@@ -22,6 +22,7 @@ int main(int argc, char *argv[])
     /* handle echo to client */
     while (1) {
        /* accept connection */
     /* handle echo to client */
     while (1) {
        /* accept connection */
+       len = sizeof(cli_add);
        while (((conn_fd = accept(list_fd, (struct sockaddr *)&cli_add, &len)) 
                < 0) && (errno == EINTR)); 
        if ( conn_fd < 0) {
        while (((conn_fd = accept(list_fd, (struct sockaddr *)&cli_add, &len)) 
                < 0) && (errno == EINTR)); 
        if ( conn_fd < 0) {
index a82f3ec70a17ca089dc086ef071181321530c325..79035f8b8a369b1b9664f3c3fd9bf3a63f744dbd 100644 (file)
@@ -8,9 +8,6 @@
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
 %% license is included in the section entitled "GNU Free Documentation
 %% License".
 %%
-\part{Programmazione di rete}
-\label{part:progr-di-rete}
-
 \chapter{Introduzione alla programmazione di rete}
 \label{cha:network}
 
 \chapter{Introduzione alla programmazione di rete}
 \label{cha:network}
 
index 1e4b12c86371e621d9d5394997e3f436e04d0446..151d77922d25e4321f67961a6d1d10cf56412644 100644 (file)
@@ -73,6 +73,9 @@ echo: TCP_echo.c
 echod: TCP_echod.c
        $(CC) $(CFLAGJ) $(CFLAGS) $^ -o $@
 
 echod: TCP_echod.c
        $(CC) $(CFLAGJ) $(CFLAGS) $^ -o $@
 
+sechod: select_echod.c
+       $(CC) $(CFLAGJ) $(CFLAGS) $^ -o $@
+
 daytimed: TCP_cunc_daytimed.c
        $(CC) $(CFLAGJ) $^ -o $@
 
 daytimed: TCP_cunc_daytimed.c
        $(CC) $(CFLAGJ) $^ -o $@
 
index 14896fa29d8cfd94611a458a297b40a0dfa202fb..9c332039a6eb7e965a61d9620a706090379d9d9a 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: daytimed -h give all info
  *
  *
  * Usage: daytimed -h give all info
  *
- * $Id: TCP_cunc_daytimed.c,v 1.3 2003/05/02 09:55:14 piccardi Exp $
+ * $Id: TCP_cunc_daytimed.c,v 1.4 2003/12/25 17:31:09 piccardi Exp $
  *
  ****************************************************************/
 /* 
  *
  ****************************************************************/
 /* 
@@ -113,8 +113,9 @@ int main(int argc, char *argv[])
     }
     /* write daytime to client */
     while (1) {
     }
     /* write daytime to client */
     while (1) {
-       if ( (conn_fd = accept(list_fd, (struct sockaddr *)&client, &len)) 
-            <0 ) {
+       len = sizeof(client);
+       if ( (conn_fd = 
+             accept(list_fd, (struct sockaddr *)&client, &len)) <0 ) {
            perror("accept error");
            exit(-1);
        }
            perror("accept error");
            exit(-1);
        }
index fd51f982797a745c6d5d2f1e8fc1cf3c5949b45d..dd0a9f855b3f2cb5d8295c431732c5ac36e86c5e 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: echod -h give all info
  *
  *
  * Usage: echod -h give all info
  *
- * $Id: TCP_echod.c,v 1.12 2003/08/03 18:12:47 piccardi Exp $ 
+ * $Id: TCP_echod.c,v 1.13 2003/12/25 17:31:09 piccardi Exp $ 
  *
  ****************************************************************/
 /* 
  *
  ****************************************************************/
 /* 
@@ -42,6 +42,8 @@
 #include <signal.h>      /* signal functions */
 #include <errno.h>       /* error code */
 #include <string.h>      /* error strings */
 #include <signal.h>      /* signal functions */
 #include <errno.h>       /* error code */
 #include <string.h>      /* error strings */
+#include <stdlib.h>
+
 #include "Gapil.h"
 
 #define BACKLOG 10
 #include "Gapil.h"
 
 #define BACKLOG 10
@@ -153,9 +155,10 @@ int main(int argc, char *argv[])
     /* handle echo to client */
     while (1) {
        /* accept connection */
     /* handle echo to client */
     while (1) {
        /* accept connection */
+       len = sizeof(cli_add);
        while (((conn_fd = accept(list_fd, (struct sockaddr *)&cli_add, &len)) 
                < 0) && (errno == EINTR)); 
        while (((conn_fd = accept(list_fd, (struct sockaddr *)&cli_add, &len)) 
                < 0) && (errno == EINTR)); 
-       if ( conn_fd < 0) {
+       if (conn_fd < 0) {
            PrintErr("accept error");
            exit(1);
        }
            PrintErr("accept error");
            exit(1);
        }
index b1356fe3f55213daae0bf5109fa2c1fa22c47370..bfe826a8c76d7ad61a05ac032390c32cb456d5b4 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: echod -h give all info
  *
  *
  * Usage: echod -h give all info
  *
- * $Id: TCP_echod_first.c,v 1.2 2003/07/27 23:41:04 piccardi Exp $ 
+ * $Id: TCP_echod_first.c,v 1.3 2003/12/25 17:31:09 piccardi Exp $ 
  *
  ****************************************************************/
 /* 
  *
  ****************************************************************/
 /* 
@@ -42,6 +42,8 @@
 #include <signal.h>      /* signal functions */
 #include <errno.h>       /* error code */
 #include <string.h>      /* error strings */
 #include <signal.h>      /* signal functions */
 #include <errno.h>       /* error code */
 #include <string.h>      /* error strings */
+#include <stdlib.h>
+
 #include "Gapil.h"
 
 #define BACKLOG 10
 #include "Gapil.h"
 
 #define BACKLOG 10
@@ -138,6 +140,7 @@ int main(int argc, char *argv[])
     /* handle echo to client */
     while (1) {
        /* accept connection */
     /* handle echo to client */
     while (1) {
        /* accept connection */
+       len = sizeof(cli_add);
        if ( (conn_fd = accept(list_fd, NULL, NULL)) < 0) {
            PrintErr("accept error");
            exit(1);
        if ( (conn_fd = accept(list_fd, NULL, NULL)) < 0) {
            PrintErr("accept error");
            exit(1);
index 4519b29e3d3e3e63e3e18dd60448ff095dc0e119..617eaf14dcee91572b4c66a940b9bfc59846f27c 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: echod -h give all info
  *
  *
  * Usage: echod -h give all info
  *
- * $Id: TCP_echod_second.c,v 1.1 2003/08/03 18:12:47 piccardi Exp $ 
+ * $Id: TCP_echod_second.c,v 1.2 2003/12/25 17:31:09 piccardi Exp $ 
  *
  ****************************************************************/
 /* 
  *
  ****************************************************************/
 /* 
@@ -42,6 +42,8 @@
 #include <signal.h>      /* signal functions */
 #include <errno.h>       /* error code */
 #include <string.h>      /* error strings */
 #include <signal.h>      /* signal functions */
 #include <errno.h>       /* error code */
 #include <string.h>      /* error strings */
+#include <stdlib.h>
+
 #include "Gapil.h"
 
 #define BACKLOG 10
 #include "Gapil.h"
 
 #define BACKLOG 10
@@ -153,6 +155,7 @@ int main(int argc, char *argv[])
     /* handle echo to client */
     while (1) {
        /* accept connection */
     /* handle echo to client */
     while (1) {
        /* accept connection */
+       len = sizeof(cli_add);
        while (((conn_fd = accept(list_fd, (struct sockaddr *)&cli_add, &len)) 
                < 0) && (errno == EINTR)); 
        if ( conn_fd < 0) {
        while (((conn_fd = accept(list_fd, (struct sockaddr *)&cli_add, &len)) 
                < 0) && (errno == EINTR)); 
        if ( conn_fd < 0) {
diff --git a/sources/select_echod.c b/sources/select_echod.c
new file mode 100644 (file)
index 0000000..b1b6483
--- /dev/null
@@ -0,0 +1,243 @@
+/* select_echod.c
+ * 
+ * Copyright (C) 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 select_echod 
+ * Elementary TCP server for echo service (port 7) using select
+ *
+ * Author: Simone Piccardi
+ * Dec. 2003
+ *
+ * Usage: echod -h give all info
+ *
+ * $Id: select_echod.c,v 1.1 2003/12/25 17:31:09 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 <time.h>
+#include <syslog.h>      /* syslog system functions */
+#include <signal.h>      /* signal functions */
+#include <errno.h>       /* error code */
+#include <string.h>      /* error strings */
+#include <stdlib.h>
+
+#include "Gapil.h"
+
+#define BACKLOG 10
+#define MAXLINE 256
+int demonize  = 1;  /* daemon use option: default is daemon */
+int debugging = 0;  /* debug info printing option: default is no debug */
+/* Subroutines declaration */
+void usage(void);
+void PrintErr(char * error);
+/* Program beginning */
+int main(int argc, char *argv[])
+{
+/* 
+ * Variables definition  
+ */
+    int waiting = 0;
+    int compat = 0;
+    struct sockaddr_in serv_add, cli_add;
+    socklen_t len;
+    char buffer[MAXLINE];
+    char fd_open[FD_SETSIZE];
+    fd_set fset;
+    int list_fd, fd;
+    int max_fd, nread, nwrite;
+    int i, n;
+    /*
+     * Input section: decode parameters passed in the calling 
+     * Use getopt function
+     */
+    opterr = 0;         /* don't want writing to stderr */
+    while ( (i = getopt(argc, argv, "hdicw:")) != -1) {
+       switch (i) {
+       /* 
+        * Handling options 
+        */ 
+       case 'h':  
+           printf("Wrong -h option use\n");
+           usage();
+           return(0);
+           break;
+       case 'i':
+           demonize = 0;
+           break;
+       case 'c':
+           compat = 1;
+           break;
+       case 'd':
+           debugging = 1;
+           break;
+       case 'w':
+           waiting = strtol(optarg, NULL, 10);
+           break;
+       case '?':   /* unrecognized options */
+           printf("Unrecognized options -%c\n",optopt);
+           usage();
+       default:    /* should not reached */
+           usage();
+       }
+    }
+    /* ***********************************************************
+     * 
+     *          Options processing completed
+     *
+     *               Main code beginning
+     * 
+     * ***********************************************************/
+    /* Main code begin here */
+    if (compat) {                             /* install signal handler */
+       Signal(SIGCHLD, HandSigCHLD);         /* non restarting handler */
+    } else {
+       SignalRestart(SIGCHLD, HandSigCHLD);  /* restarting handler */
+    }
+    /* create socket */
+    if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+       perror("Socket creation error");
+       exit(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 */
+    serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
+    /* bind socket */
+    if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+       perror("bind error");
+       exit(1);
+    }
+    /* release privileges and go daemon */
+    if (setgid(65534) !=0) { /* first give away group privileges */
+       perror("cannot give away group privileges");
+       exit(1);
+    }
+    if (setuid(65534) !=0) { /* and only after user ... */
+       perror("cannot give away user privileges");
+       exit(1);
+    }
+    if (demonize) {          /* go daemon */
+        openlog(argv[0], 0, LOG_DAEMON); /* open logging */
+       if (daemon(0, 0) != 0) {
+           perror("cannot start as daemon");
+           exit(1);
+       }
+    }
+    /* main body */
+    if (listen(list_fd, BACKLOG) < 0 ) {
+       PrintErr("listen error");
+       exit(1);
+    }
+    if (waiting) sleep(waiting);
+    /* initialize all needed variables */
+    memset(fd_open, 0, FD_SETSIZE);   /* clear array of open files */
+    max_fd = list_fd;                 /* set maximum fd to look */
+    fd_open[max_fd] = 1;
+    /* main loop, wait for connection and data inside a select */
+    while (1) {    
+       FD_ZERO(&fset);               /* clear fd_set */
+       for (i = list_fd; i <= max_fd; i++) {
+           if (fd_open[i]) FD_SET(i, &fset); /* initialize open sockets */
+       }
+       while ( ((n = select(max_fd + 1, &fset, NULL, NULL, NULL)) < 0) 
+               && (errno == EINTR));
+       /* there are data */
+       if (n < 0) {
+           PrintErr("select error");
+           exit(1);
+       }       
+       if (FD_ISSET(list_fd, &fset)) { /* if data on listening socket */
+           len = sizeof(cli_add);
+           fd = accept(list_fd, (struct sockaddr *)&cli_add, &len); 
+           if (fd < 0) {
+               PrintErr("accept error");
+               exit(1);
+           }
+           fd_open[fd] = 1;
+           if (max_fd < fd) max_fd = fd;
+           FD_SET(fd, &fset);
+           n--;
+       }
+       for (i = list_fd + 1; i <= max_fd; i++) {
+           if (fd_open[i] == 0) continue;
+           if (FD_ISSET(i, &fset)) {
+               n--;
+               nread = read(fd, buffer, MAXLINE);
+               if (nread < 0) {
+                   PrintErr("Errore in lettura");
+                   exit(1);
+               }
+               if (nread == 0) {
+                   fd_open[i] = 0;
+                   if (max_fd == i) {
+                       while (fd_open[i] == 0) {
+                           i--;
+                       }
+                       max_fd = i;
+                       break;
+                   }
+                   continue;
+               }
+               nwrite = FullWrite(fd, buffer, nread);
+               if (nwrite) {
+                   PrintErr("Errore in scrittura");
+                   exit(1);
+               }
+           }
+       }
+       if (n != 0) {
+           PrintErr("Errore nella gestione dei file descriptor");
+       }
+    }
+    /* normal exit, never reached */
+    exit(0);
+}
+/*
+ * routine to print usage info and exit
+ */
+void usage(void) {
+    printf("Elementary echo server\n");
+    printf("Usage:\n");
+    printf("  echod [-h] \n");
+    printf("  -h          print this help\n");
+    printf("  -d          write debug info\n");
+    printf("  -i          use interactively\n");
+    printf("  -c          disable BSD semantics\n");
+    printf("  -w N        wait N sec. before calling accept\n");
+    exit(1);
+}
+/*
+ * routine to print error on stout or syslog
+ */
+void PrintErr(char * error) {
+    if (demonize) {                       /* daemon mode */
+       syslog(LOG_ERR, "%s: %m", error); /* log string and error message */
+    } else {
+       perror(error);
+    }
+    return;
+}
index 852e4a6bf16950054137ab481c0453a2b690060c..35c5ef2cd5d73573ce76357c6ef9be0a5288ad56 100644 (file)
@@ -635,8 +635,11 @@ precedente in \secref{sec:sock_socket}.
 \subsection{La funzione \func{bind}}
 \label{sec:TCP_func_bind}
 
 \subsection{La funzione \func{bind}}
 \label{sec:TCP_func_bind}
 
-La funzione \funcd{bind} assegna un indirizzo locale ad un socket. È usata
-cioè per specificare la prima parte dalla socket pair. Viene usata sul lato
+La funzione \funcd{bind} assegna un indirizzo locale ad un
+socket.\footnote{nel nostro caso la utilizzeremo per socket TCP, ma la
+  funzione è generica e deve essere usata per qualunque tipo di socket
+  \texttt{SOCK\_STREAM} prima che questo possa accettare connessioni.} È usata
+cioè per specificare la prima parte dalla socket pair.  Viene usata sul lato
 server per specificare la porta (e gli eventuali indirizzi locali) su cui poi
 ci si porrà in ascolto. Il prototipo della funzione è il seguente:
 \begin{prototype}{sys/socket.h}
 server per specificare la porta (e gli eventuali indirizzi locali) su cui poi
 ci si porrà in ascolto. Il prototipo della funzione è il seguente:
 \begin{prototype}{sys/socket.h}
@@ -746,9 +749,17 @@ staticamente a \const{IN6ADRR\_LOOPBACK\_INIT}.
 \label{sec:TCP_func_connect}
 
 La funzione \funcd{connect} è usata da un client TCP per stabilire la
 \label{sec:TCP_func_connect}
 
 La funzione \funcd{connect} è usata da un client TCP per stabilire la
-connessione con un server TCP, il prototipo della funzione è il seguente:
+connessione con un server TCP,\footnote{di nuovo la funzione è generica e
+  supporta vari tipi di socket, la differenza è che per socket senza
+  connessione come quelli di tipo \texttt{SOCK\_DGRAM} la sua chiamata si
+  limiterà ad impostare l'indirizzo dal quale e verso il quale saranno inviati
+  e ricevuti i pacchetti, mentre per socket di tipo \texttt{SOCK\_STREAM} o
+  \texttt{SOCK\_SEQPACKET}, essa attiverà la procedura di avvio (nel caso del
+  TCP il \textit{three-way-handsjake}) della connessione.}  il prototipo della
+funzione è il seguente:
 \begin{prototype}{sys/socket.h}
 \begin{prototype}{sys/socket.h}
-{int connect(int sockfd, const struct sockaddr *servaddr, socklen\_t addrlen)}
+  {int connect(int sockfd, const struct sockaddr *servaddr, socklen\_t
+    addrlen)}
   
   Stabilisce una connessione fra due socket.
   
   
   Stabilisce una connessione fra due socket.
   
@@ -848,12 +859,14 @@ necessario effettuare una \func{bind}.
 \label{sec:TCP_func_listen}
 
 La funzione \funcd{listen} serve ad usare un socket in modalità passiva, cioè,
 \label{sec:TCP_func_listen}
 
 La funzione \funcd{listen} serve ad usare un socket in modalità passiva, cioè,
-come dice il nome, per metterlo in ascolto di eventuali connessioni; in
-sostanza l'effetto della funzione è di portare il socket dallo stato
-\texttt{CLOSED} a quello \texttt{LISTEN}. In genere si chiama la funzione in
-un server dopo le chiamate a \func{socket} e \func{bind} e prima della
-chiamata ad \func{accept}. Il prototipo della funzione, come definito dalla
-pagina di manuale, è:
+come dice il nome, per metterlo in ascolto di eventuali
+connessioni;\footnote{questa funzione può essere usata con socket che
+  supportino le connessioni, cioè di tipo \texttt{SOCK\_STREAM} o
+  \texttt{SOCK\_SEQPACKET}.} in sostanza l'effetto della funzione è di portare
+il socket dallo stato \texttt{CLOSED} a quello \texttt{LISTEN}. In genere si
+chiama la funzione in un server dopo le chiamate a \func{socket} e \func{bind}
+e prima della chiamata ad \func{accept}. Il prototipo della funzione, come
+definito dalla pagina di manuale, è:
 \begin{prototype}{sys/socket.h}{int listen(int sockfd, int backlog)}
   Pone un socket in attesa di una connessione.
   
 \begin{prototype}{sys/socket.h}{int listen(int sockfd, int backlog)}
   Pone un socket in attesa di una connessione.
   
@@ -972,10 +985,13 @@ trasparente dal protocollo TCP.
 \label{sec:TCP_func_accept}
 
 La funzione \funcd{accept} è chiamata da un server per gestire la connessione
 \label{sec:TCP_func_accept}
 
 La funzione \funcd{accept} è chiamata da un server per gestire la connessione
-una volta che sia stato completato il \textit{three way handshake}, la
-funzione restituisce un nuovo socket descriptor su cui si potrà operare per
-effettuare la comunicazione. Se non ci sono connessioni completate il processo
-viene messo in attesa. Il prototipo della funzione è il seguente:
+una volta che sia stato completato il \textit{three way
+  handshake},\footnote{la funzione è comunque generica ed è utilizzabile su
+  socket di tipo \texttt{SOCK\_STREAM}, \texttt{SOCK\_SEQPACKET} e
+  \texttt{SOCK\_RDM}.} la funzione restituisce un nuovo socket descriptor su
+cui si potrà operare per effettuare la comunicazione. Se non ci sono
+connessioni completate il processo viene messo in attesa. Il prototipo della
+funzione è il seguente:
 \begin{prototype}{sys/socket.h}
 {int accept(int sockfd, struct sockaddr *addr, socklen\_t *addrlen)} 
  
 \begin{prototype}{sys/socket.h}
 {int accept(int sockfd, struct sockaddr *addr, socklen\_t *addrlen)} 
  
@@ -1514,21 +1530,21 @@ degli altri esempi.
   \label{fig:TCP_daytime_cunc_server_code}
 \end{figure}
 
   \label{fig:TCP_daytime_cunc_server_code}
 \end{figure}
 
-Stavolta (\texttt{\small 21--25}) la funzione \func{accept} è chiamata
+Stavolta (\texttt{\small 21--26}) la funzione \func{accept} è chiamata
 fornendo una struttura di indirizzi in cui saranno ritornati l'indirizzo IP e
 la porta da cui il client effettua la connessione, che in un secondo tempo,
 fornendo una struttura di indirizzi in cui saranno ritornati l'indirizzo IP e
 la porta da cui il client effettua la connessione, che in un secondo tempo,
-(\texttt{\small 39--43}), se il logging è abilitato, stamperemo sullo standard
+(\texttt{\small 40--44}), se il logging è abilitato, stamperemo sullo standard
 output.
 
 Quando \func{accept} ritorna il server chiama la funzione \func{fork}
 output.
 
 Quando \func{accept} ritorna il server chiama la funzione \func{fork}
-(\texttt{\small 26--30}) per creare il processo figlio che effettuerà
-(\texttt{\small 31--45}) tutte le operazioni relative a quella connessione,
+(\texttt{\small 27--31}) per creare il processo figlio che effettuerà
+(\texttt{\small 32--46}) tutte le operazioni relative a quella connessione,
 mentre il padre proseguirà l'esecuzione del ciclo principale in attesa di
 ulteriori connessioni.
 
 Si noti come il figlio operi solo sul socket connesso, chiudendo
 mentre il padre proseguirà l'esecuzione del ciclo principale in attesa di
 ulteriori connessioni.
 
 Si noti come il figlio operi solo sul socket connesso, chiudendo
-immediatamente (\texttt{\small 32}) il socket \var{list\_fd}; mentre il padre
-continua ad operare (\texttt{\small 47}) solo sul socket in ascolto chiudendo
+immediatamente (\texttt{\small 33}) il socket \var{list\_fd}; mentre il padre
+continua ad operare solo sul socket in ascolto chiudendo (\texttt{\small 48})
 \var{sock\_fd} al ritorno dalla \func{fork}. Per quanto abbiamo detto in
 \secref{sec:TCP_func_close} nessuna delle due chiamate a \func{close} causa
 l'innesco della sequenza di chiusura perché il numero di riferimenti al file
 \var{sock\_fd} al ritorno dalla \func{fork}. Per quanto abbiamo detto in
 \secref{sec:TCP_func_close} nessuna delle due chiamate a \func{close} causa
 l'innesco della sequenza di chiusura perché il numero di riferimenti al file
@@ -1540,7 +1556,7 @@ lo stesso vale per \var{sock\_fd} dopo il ritorno di \func{accept}, ma dopo la
 entrambi i socket si trovano con due referenze. Questo fa si che quando il
 padre chiude \var{sock\_fd} esso resta con una referenza da parte del figlio,
 e sarà definitivamente chiuso solo quando quest'ultimo, dopo aver completato
 entrambi i socket si trovano con due referenze. Questo fa si che quando il
 padre chiude \var{sock\_fd} esso resta con una referenza da parte del figlio,
 e sarà definitivamente chiuso solo quando quest'ultimo, dopo aver completato
-le sue operazioni, chiamerà (\texttt{\small 44}) la funzione \func{close}.
+le sue operazioni, chiamerà (\texttt{\small 45}) la funzione \func{close}.
 
 In realtà per il figlio non sarebbe necessaria nessuna chiamata a
 \func{close}, in quanto con la \func{exit} finale (\texttt{\small 45}) tutti i
 
 In realtà per il figlio non sarebbe necessaria nessuna chiamata a
 \func{close}, in quanto con la \func{exit} finale (\texttt{\small 45}) tutti i
@@ -1559,18 +1575,18 @@ per ogni processo) e soprattutto nessuna delle connessioni con i client
 verrebbe chiusa.
 
 Come per ogni server iterativo il lavoro di risposta viene eseguito
 verrebbe chiusa.
 
 Come per ogni server iterativo il lavoro di risposta viene eseguito
-interamente dal processo figlio. Questo si incarica (\texttt{\small 33}) di
+interamente dal processo figlio. Questo si incarica (\texttt{\small 34}) di
 chiamare \func{time} per leggere il tempo corrente, e di stamparlo
 chiamare \func{time} per leggere il tempo corrente, e di stamparlo
-(\texttt{\small 34}) sulla stringa contenuta in \var{buffer} con l'uso di
+(\texttt{\small 35}) sulla stringa contenuta in \var{buffer} con l'uso di
 \func{snprintf} e \func{ctime}. Poi la stringa viene scritta (\texttt{\small
 \func{snprintf} e \func{ctime}. Poi la stringa viene scritta (\texttt{\small
-  35--38}) sul socket, controllando che non ci siano errori. Anche in questo
+  36--39}) sul socket, controllando che non ci siano errori. Anche in questo
 caso si è evitato il ricorso a \func{FullWrite} in quanto la stringa è
 estremamente breve e verrà senz'altro scritta in un singolo segmento.
 
 Inoltre nel caso sia stato abilitato il \textit{logging} delle connessioni, si
 caso si è evitato il ricorso a \func{FullWrite} in quanto la stringa è
 estremamente breve e verrà senz'altro scritta in un singolo segmento.
 
 Inoltre nel caso sia stato abilitato il \textit{logging} delle connessioni, si
-provvede anche (\texttt{\small 39--42}) a stampare sullo standard output
-l'indirizzo e la porta da cui il client ha effettuato la connessione, usando
-valori contenuti nelle strutture restituite da \func{accept}, eseguendo le
+provvede anche (\texttt{\small 40--43}) a stampare sullo standard output
+l'indirizzo e la porta da cui il client ha effettuato la connessione, usando i
+valori contenuti nelle strutture restituite da \func{accept}, eseguendo le
 opportune conversioni con \func{inet\_ntop} e \func{atohs}.
 
 Ancora una volta l'esempio è estremamente semplificato, si noti come di nuovo
 opportune conversioni con \func{inet\_ntop} e \func{atohs}.
 
 Ancora una volta l'esempio è estremamente semplificato, si noti come di nuovo
@@ -1779,15 +1795,15 @@ alla funzione \code{PrintErr}, riportata in \figref{fig:TCP_PrintErr}, al
 posto di \func{perror} per la stampa degli errori. 
 
 Si inizia con il porre (\texttt{\small 37--41}) in ascolto il socket, e poi si
 posto di \func{perror} per la stampa degli errori. 
 
 Si inizia con il porre (\texttt{\small 37--41}) in ascolto il socket, e poi si
-esegue indefinitamente il ciclo principale (\texttt{\small 42--58}).
-All'interno di questo si ricevono (\texttt{\small 43--46}) le connessioni,
-creando (\texttt{\small 47--50}) un processo figlio per ciascuna di esse.
-Quest'ultimo (\texttt{\small 51--55}), chiuso (\texttt{\small 52}) il
-\textit{listening socket}, esegue (\texttt{\small 53}) la funzione di gestione
-del servizio \code{ServEcho}, ed al ritorno di questa (\texttt{\small 54})
-esce.
-
-Il padre invece si limita (\texttt{\small 56}) a chiudere il \textit{connected
+esegue indefinitamente il ciclo principale (\texttt{\small 42--59}).
+All'interno di questo si ricevono (\texttt{\small 43--47}) le connessioni,
+creando (\texttt{\small 48--51}) un processo figlio per ciascuna di esse.
+Quest'ultimo (\texttt{\small 52--56}), chiuso (\texttt{\small 53}) il
+\textit{listening socket}, esegue (\texttt{\small 54}) la funzione di gestione
+del servizio \code{ServEcho}, ed al ritorno di questa esce (\texttt{\small
+  55}).
+
+Il padre invece si limita (\texttt{\small 57}) a chiudere il \textit{connected
   socket} per ricominciare da capo il ciclo in attesa di nuove connessioni. In
 questo modo si ha un server concorrente. La terminazione del padre non è
 gestita esplicitamente, e deve essere effettuata inviando un segnale al
   socket} per ricominciare da capo il ciclo in attesa di nuove connessioni. In
 questo modo si ha un server concorrente. La terminazione del padre non è
 gestita esplicitamente, e deve essere effettuata inviando un segnale al
@@ -2143,7 +2159,7 @@ figli stessi e non risentono di \const{SIGCHLD}.
 
 Per questo l'unica modifica sostanziale nel ciclo principale (\texttt{\small
   23--42}), rispetto precedente versione di \figref{fig:TCP_ServEcho_first}, è
 
 Per questo l'unica modifica sostanziale nel ciclo principale (\texttt{\small
   23--42}), rispetto precedente versione di \figref{fig:TCP_ServEcho_first}, è
-nella sezione (\texttt{\small 26--30}) in cui si effettua la chiamata di
+nella sezione (\texttt{\small 25--31}) in cui si effettua la chiamata di
 \func{accept}.  Quest'ultima viene effettuata (\texttt{\small 26--27})
 all'interno di un ciclo di \code{while}\footnote{la sintassi del C relativa a
   questo ciclo può non essere del tutto chiara. In questo caso infatti si è
 \func{accept}.  Quest'ultima viene effettuata (\texttt{\small 26--27})
 all'interno di un ciclo di \code{while}\footnote{la sintassi del C relativa a
   questo ciclo può non essere del tutto chiara. In questo caso infatti si è
@@ -2155,12 +2171,12 @@ altri casi si esce in caso di errore effettivo (\texttt{\small 27--29}),
 altrimenti il programma prosegue.
 
 Si noti che in questa nuova versione si è aggiunta una ulteriore sezione
 altrimenti il programma prosegue.
 
 Si noti che in questa nuova versione si è aggiunta una ulteriore sezione
-(\texttt{\small 31--39}) di aiuto per il debug del programma, che eseguita con
-un controllo (\texttt{\small 31}) sul valore della variabile \var{debugging}
+(\texttt{\small 32--40}) di aiuto per il debug del programma, che eseguita con
+un controllo (\texttt{\small 33}) sul valore della variabile \var{debugging}
 impostato dall'opzione \texttt{-d}. Qualora questo sia nullo, come
 impostato dall'opzione \texttt{-d}. Qualora questo sia nullo, come
-preimpostato, non accade nulla. altrimenti (\texttt{\small 32}) l'indirizzo
+preimpostato, non accade nulla. altrimenti (\texttt{\small 33}) l'indirizzo
 ricevuto da \var{accept} viene convertito in una stringa che poi
 ricevuto da \var{accept} viene convertito in una stringa che poi
-(\texttt{\small 33--38}) viene opportunamente stampata o sullo schermo o nei
+(\texttt{\small 34--39}) viene opportunamente stampata o sullo schermo o nei
 log.
 
 
 log.