From 958940edc920cda07bd217027477f916e40a252e Mon Sep 17 00:00:00 2001
From: Guo Wenxue <guowenxue@gmail.com>
Date: Mon, 26 Nov 2018 11:33:10 +0800
Subject: [PATCH] Add socket_server select array implement and rename list implement

---
 ch5_multiplexing/socket_server_select_list.c  |    3 
 ch5_multiplexing/socket_server_select_array.c |  153 ++++++++++++++++----------------------------------
 2 files changed, 50 insertions(+), 106 deletions(-)

diff --git a/ch5_multiplexing/socket_server_select.c b/ch5_multiplexing/socket_server_select_array.c
similarity index 66%
copy from ch5_multiplexing/socket_server_select.c
copy to ch5_multiplexing/socket_server_select_array.c
index cd98c02..c5a6d15 100644
--- a/ch5_multiplexing/socket_server_select.c
+++ b/ch5_multiplexing/socket_server_select_array.c
@@ -13,20 +13,11 @@
 #include <arpa/inet.h>
 #include <netinet/in.h> 
 
-
-typedef struct link_node_s 
-{
-    int                   fd;  
-    struct link_node_s   *next;
-} link_node_t;  
-
+#define ARRAY_SIZE(x)       (sizeof(x)/sizeof(x[0]))
 
 static inline void msleep(unsigned long ms);
 static inline void print_usage(char *progname);
 int socket_server_init(char *listen_ip, int listen_port);
-int add_fd_list(link_node_t  **head, int fd);
-link_node_t *list_remove_node(link_node_t  **head, link_node_t *node);
-
 
 int main(int argc, char **argv)
 {
@@ -34,15 +25,14 @@
     int                       serv_port = 0;
     int                       daemon_run = 0;
     char                     *progname = NULL;
-    pthread_t                 tid;
     int                       opt;
     fd_set                    rdset; 
-    link_node_t              *client_list = NULL; /* client fd link list, we will not use arrary for it get max client limite */
-    link_node_t              *node;
     int                       rv;
-    int                       i;
+    int                       i, j;
+    int                       found;
     int                       maxfd=0;
     char                      buf[1024];
+    int                       fds_array[1024];
 
     struct option             long_options[] = 
     {   
@@ -96,17 +86,23 @@
         daemon(0, 0);
     }
 
-    printf("add listen socket[%d] into client list\n", listenfd );
-    add_fd_list(&client_list, listenfd);
+    for(i=0; i<ARRAY_SIZE(fds_array) ; i++)
+    {
+	    fds_array[i]=-1;
+    }
+    fds_array[0] = listenfd;
+
 
     for ( ; ; ) 
     {
         FD_ZERO(&rdset);
-       	for( node=client_list; node!=NULL; node=node->next ) 
+       	for(i=0; i<ARRAY_SIZE(fds_array) ; i++)
 	{
-	    //printf("Add socket[%d] in select readset\n", node->fd);
-	    maxfd = node->fd>maxfd ? node->fd : maxfd;
-	    FD_SET(node->fd, &rdset); 
+	    if( fds_array[i] < 0 )
+		    continue;
+
+	    maxfd = fds_array[i]>maxfd ? fds_array[i] : maxfd;
+	    FD_SET(fds_array[i], &rdset); 
 	}
 
 	/* program will blocked here */
@@ -131,52 +127,58 @@
                 continue;
             }
 
-            printf("accept new client[%d] and add it into client list\n", connfd );
-            add_fd_list(&client_list, connfd);
+	    found = 0;
+	    for(i=0; i<ARRAY_SIZE(fds_array) ; i++)
+	    {
+	        if( fds_array[i] < 0 )
+		{
+		   printf("accept new client[%d] and add it into array\n", connfd );
+		   fds_array[i] = connfd;
+		   found = 1;
+		   break;
+		}
+	    }
+
+	    if( !found )
+	    {
+		printf("accept new client[%d] but full, so refuse it\n", connfd);
+		close(connfd);
+	    }
         }
         else /* data arrive from already connected client */
         {
-	    node = client_list;
-       	    while( node != NULL ) 
+	    for(i=0; i<ARRAY_SIZE(fds_array); i++)
 	    {
-		if( !FD_ISSET(node->fd, &rdset) )
-		{
-			node = node->next;
-			continue;
-		}
+		if( fds_array[i]<0 || !FD_ISSET(fds_array[i], &rdset) )
+		   continue;
 
-                if( (rv=read(node->fd, buf, sizeof(buf))) <= 0)
+                if( (rv=read(fds_array[i], buf, sizeof(buf))) <= 0)
                 {
-                   printf("socket[%d] read failure or get disconncet.\n", node->fd);
-		   /* list_remove_node will return the previous node */
-		   node = list_remove_node(&client_list, node); 
+                   printf("socket[%d] read failure or get disconncet.\n", fds_array[i]);
+		   close(fds_array[i]);
+		   fds_array[i] = -1;
 		}
 		else
 		{
-		    printf("socket[%d] read get %d bytes data\n", node->fd, rv);
+		    printf("socket[%d] read get %d bytes data\n", fds_array[i], rv);
 
 		    /* convert letter from lowercase to uppercase */
-		    for(i=0; i<rv; i++)
-			buf[i]=toupper(buf[i]);
+		    for(j=0; j<rv; j++)
+			buf[j]=toupper(buf[j]);
 
-                    if( write(node->fd, buf, rv) < 0 )
+                    if( write(fds_array[i], buf, rv) < 0 )
 		    {
-		        printf("socket[%d] write failure: %s\n", node->fd, strerror(errno));
-		       	/* list_remove_node will return the previous node */
-		        node = list_remove_node(&client_list, node);
+		        printf("socket[%d] write failure: %s\n", fds_array[i], strerror(errno));
+		       	close(fds_array[i]);
+		       	fds_array[i] = -1;
 		    }
 		}
-
-		if( node != NULL )
-		{
-		    node = node->next;
-		}
-            } /* while( node != NULL ) */
+            }
         }
     }
 
 CleanUp:
-    close(listenfd);  /* We must close socket File Description when program exit*/
+    close(listenfd);
     return 0;
 }
 
@@ -265,62 +267,5 @@
         rv = listenfd;
 
     return rv;
-}
-
-int add_fd_list(link_node_t  **head, int fd)
-{
-    link_node_t          *node;
-    link_node_t          *tmp;
-
-    if( NULL == (node=(link_node_t *)malloc(sizeof(*node))) ) 
-    {
-        printf("malloc for new node failure\n");
-        return -1;
-    }
-
-    memset(node, 0, sizeof(*node));
-    node->fd = fd;
-    node->next = NULL;
-
-    if( *head == NULL )
-    {
-        *head = node;
-        return 0;
-    }
-
-    tmp = *head;
-    while( tmp->next != NULL )
-    {
-        tmp=tmp->next;
-    }
-
-    tmp->next = node;
-}
-
-/* list_remove_node will return the previous node */
-link_node_t *list_remove_node(link_node_t  **head, link_node_t *node)
-{
-    link_node_t         *prev;
-
-    close(node->fd);
-
-    if( node == *head )
-    {
-	 *head = NULL;
-	 free(node);
-	 return NULL;
-    }
-    else
-    {
-        for(prev=*head; prev!=NULL; prev=prev->next) 
-        {
-	   if(prev->next == node) 
-	   { 
-	       prev->next = node->next;
-	       free(node);
-	       return prev;
-	   }
-       	}
-    }
 }
 
diff --git a/ch5_multiplexing/socket_server_select.c b/ch5_multiplexing/socket_server_select_list.c
similarity index 98%
rename from ch5_multiplexing/socket_server_select.c
rename to ch5_multiplexing/socket_server_select_list.c
index cd98c02..39a066e 100644
--- a/ch5_multiplexing/socket_server_select.c
+++ b/ch5_multiplexing/socket_server_select_list.c
@@ -34,7 +34,6 @@
     int                       serv_port = 0;
     int                       daemon_run = 0;
     char                     *progname = NULL;
-    pthread_t                 tid;
     int                       opt;
     fd_set                    rdset; 
     link_node_t              *client_list = NULL; /* client fd link list, we will not use arrary for it get max client limite */
@@ -176,7 +175,7 @@
     }
 
 CleanUp:
-    close(listenfd);  /* We must close socket File Description when program exit*/
+    close(listenfd); 
     return 0;
 }
 

--
Gitblit v1.9.1