Inserito esempio di server echo basato su select.
[gapil.git] / sources / select_echod.c
index b1b64832693e59656d38ae21177770227e678839..3a0690bb5b283bfc5acbc02ffcc09e67f49d9a33 100644 (file)
@@ -26,7 +26,7 @@
  *
  * Usage: echod -h give all info
  *
- * $Id: select_echod.c,v 1.1 2003/12/25 17:31:09 piccardi Exp $ 
+ * $Id: select_echod.c,v 1.2 2003/12/25 22:16:06 piccardi Exp $ 
  *
  ****************************************************************/
 /* 
@@ -44,6 +44,7 @@
 #include <string.h>      /* error strings */
 #include <stdlib.h>
 
+#include "macros.h"
 #include "Gapil.h"
 
 #define BACKLOG 10
@@ -61,7 +62,7 @@ int main(int argc, char *argv[])
  */
     int waiting = 0;
     int compat = 0;
-    struct sockaddr_in serv_add, cli_add;
+    struct sockaddr_in s_addr, c_addr;
     socklen_t len;
     char buffer[MAXLINE];
     char fd_open[FD_SETSIZE];
@@ -122,12 +123,12 @@ int main(int argc, char *argv[])
        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 */
+    memset((void *)&s_addr, 0, sizeof(s_addr));   /* clear server address */
+    s_addr.sin_family = AF_INET;                  /* address type is INET */
+    s_addr.sin_port = htons(7);                   /* echo port is 7 */
+    s_addr.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
     /* bind socket */
-    if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+    if (bind(list_fd, (struct sockaddr *)&s_addr, sizeof(s_addr)) < 0) {
        perror("bind error");
        exit(1);
     }
@@ -155,63 +156,67 @@ int main(int argc, char *argv[])
     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 */
+    max_fd = list_fd;                 /* maximum now is listening socket */
     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 */
+       for (i = list_fd; i <= max_fd; i++) { /* initialize fd_set */
+           if (fd_open[i] != 0) FD_SET(i, &fset); 
        }
        while ( ((n = select(max_fd + 1, &fset, NULL, NULL, NULL)) < 0) 
-               && (errno == EINTR));
-       /* there are data */
-       if (n < 0) {
+               && (errno == EINTR));         /* wait for data or connection */
+       if (n < 0) {                          /* on real error exit */
            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) {
+       }
+       /* on activity */
+       debug("Trovati %d socket attivi\n", n);
+       if (FD_ISSET(list_fd, &fset)) {       /* if new connection */
+           n--;                              /* decrement active */
+           len = sizeof(c_addr);             /* and call accept */
+           if ((fd = accept(list_fd, (struct sockaddr *)&c_addr, &len)) < 0) {
                PrintErr("accept error");
                exit(1);
            }
-           fd_open[fd] = 1;
-           if (max_fd < fd) max_fd = fd;
-           FD_SET(fd, &fset);
-           n--;
+           debug("Connessione su fd %d restano %d socket attivi\n", fd, n);
+           fd_open[fd] = 1;                  /* set new connection socket */
+           if (max_fd < fd) max_fd = fd;     /* if needed set new maximum */
+           debug("max_fd=%d\n", max_fd);
        }
-       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);
+       /* loop on open connections */
+       i = list_fd;                  /* first socket to look */
+       while (n != 0) {              /* loop until active */
+           i++;                      /* start after listening socket */
+           debug("restano %d socket, fd %d\n", n, fd);
+           if (fd_open[i] == 0) continue;   /* closed, go next */
+           if (FD_ISSET(i, &fset)) {        /* if active process it*/
+               n--;                         /* decrease active */
+               debug("dati su fd %d\n", i);
+               nread = read(i, buffer, MAXLINE);     /* read operations */
                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;
+               if (nread == 0) {            /* if closed connection */
+                   debug("fd %d chiuso\n", i);
+                   close(i);                /* close file */
+                   fd_open[i] = 0;          /* mark as closed in table */
+                   if (max_fd == i) {       /* if was the maximum */
+                       while (fd_open[--i] == 0);    /* loop down */
+                       max_fd = i;          /* set new maximum */
+                       debug("nuovo max_fd %d\n", max_fd);
+                       break;               /* and go back to select */
                    }
-                   continue;
+                   continue;                /* continue loop on open */
                }
-               nwrite = FullWrite(fd, buffer, nread);
+               nwrite = FullWrite(i, buffer, nread); /* write data */
                if (nwrite) {
                    PrintErr("Errore in scrittura");
                    exit(1);
                }
            }
        }
-       if (n != 0) {
-           PrintErr("Errore nella gestione dei file descriptor");
-       }
     }
     /* normal exit, never reached */
     exit(0);