From b0053f87034ff358b7ccadc7f2d9643e9a7767e7 Mon Sep 17 00:00:00 2001
From: guowenxue <guowenxue@gmail.com>
Date: Thu, 30 Apr 2020 16:15:09 +0800
Subject: [PATCH] update tlv project for server

---
 prj1_tlv/tlv_server.c |  115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 110 insertions(+), 5 deletions(-)

diff --git a/prj1_tlv/tlv_server.c b/prj1_tlv/tlv_server.c
index f0e2d56..64782a4 100644
--- a/prj1_tlv/tlv_server.c
+++ b/prj1_tlv/tlv_server.c
@@ -19,10 +19,15 @@
 
 #include "logger.h"
 #include "proc.h"
+#include "socket.h"
 
 #define PROG_VERSION     "1.0.0"
 
 #define DEF_LOG_FILE     "tlv_server.log"
+#define DEF_LISTEN_IP    "0.0.0.0"
+#define DEF_LISTEN_PORT  10086
+
+#define MAX_EVENTS       512
 
 static void banner(void)
 {
@@ -52,8 +57,9 @@
 { 
     int                   opt; 
     int                   i = 0; 
-    //int                   rv = 0; 
+    int                   rv = 0; 
     int                   debug = 0;
+    int                   port = DEF_LISTEN_PORT;
 
     char                  pid_file[64] = { 0 }; /* The file used to record the PID */
     const char           *progname=NULL;
@@ -62,7 +68,15 @@
     char                 *log_file = DEF_LOG_FILE;
     logger_t              logger;
 
+    socket_t              sock;
+    int                   epollfd;
+    int                   connfd;
+    struct epoll_event    event_array[MAX_EVENTS];
+
+    char                  buf[1024];
+
     struct option long_options[] = { 
+        {"port", required_argument, NULL, 'p'}, 
         {"debug", no_argument, NULL, 'd'}, 
         {"level", required_argument, NULL, 'l'}, 
         {"version", no_argument, NULL, 'v'}, 
@@ -71,14 +85,18 @@
     };
 
     memset(&logger, 0, sizeof(logger));
+    memset(&sock, 0, sizeof(sock));
 
     progname = basename(argv[0]); /* get program name */
 
     /* parser the command line parameters */ 
-    while ((opt = getopt_long(argc, argv, "c:dl:vh", long_options, NULL)) != -1) 
+    while ((opt = getopt_long(argc, argv, "p:dl:vh", long_options, NULL)) != -1) 
     { 
         switch (opt) 
         {
+            case 'p': /* listen port  */
+                port = atoi(optarg); 
+                break;
 
             case 'd': /* set debug running */
                 debug = 1;
@@ -105,6 +123,12 @@
         } 
     }
 
+    if( port <= 0 )
+    {
+        printf("ERROR: no listen port specified, refer to program usage\n\n");
+        program_usage(progname);
+    }
+
     /* check program already running or not, if already running then exit, or set running as daemon */
     snprintf(pid_file, sizeof(pid_file), "/var/run/%s.pid", progname);
     if( !debug )
@@ -114,6 +138,8 @@
             printf("Programe already running, exit now.\n");
             return -1;
         }
+
+        set_daemon_running(pid_file);
     }
 
     /* initial and open logger system */
@@ -126,13 +152,92 @@
     /* install signal proc handler */
     install_proc_signal();
 
-    log_nrml("Program start running\n");
+    log_nrml("TLV server program start running\n");
+
+    set_socket_rlimit();
+
+    if( socket_listen(&sock, DEF_LISTEN_IP, port) < 0 )
+    {
+        log_err("create listen socket failure\n");
+        return -2;
+    }
+
+    if( (epollfd=epoll_init(MAX_EVENTS, sock.fd)) < 0 )
+    {
+        log_err("initial epoll for listen socket failure\n");
+        return -2;
+    }
 
     /* g_signal.stop defined in proc.c, and will be set when catch stop signal */
     while( !g_signal.stop )
     {
-        log_dbg("Program still running\n");
-        sleep(3);
+        /* program will blocked here */ 
+        rv = epoll_wait(epollfd, event_array, MAX_EVENTS, -1/* never timeout */);
+        if( rv < 0 )
+        {
+            log_err("epoll failure: %s\n", strerror(errno));
+            continue;
+        }
+        else if( rv == 0)
+        {
+            log_err("epoll get timeout\n");
+            continue;
+        }
+
+        /* rv>0 is the active events count */ 
+        for(i=0; i<rv; i++)
+        {
+            if ( (event_array[i].events&EPOLLERR) || (event_array[i].events&EPOLLHUP) )
+            {
+                log_err("epoll_wait get error on fd[%d]: %s\n", event_array[i].data.fd, strerror(errno));
+                epoll_del(epollfd, event_array[i].data.fd);
+                close(event_array[i].data.fd);
+            }
+
+            /* listen socket get event means new client start connect now */ 
+            if( event_array[i].data.fd == sock.fd )
+            {
+                struct epoll_event       event;
+                if( (connfd=accept(sock.fd, (struct sockaddr *)NULL, NULL)) < 0)
+                {
+                    log_nrml("accept new client failure: %s\n", strerror(errno));
+                    continue;
+                }
+                log_info("accept new client socket[%d]\n", connfd);
+
+                event.data.fd = connfd;
+                event.events =  EPOLLIN;
+                epoll_ctl(epollfd, EPOLL_CTL_ADD, connfd, &event);
+
+#if 0
+                if( epoll_add(epollfd, connfd) < 0 )
+                {
+                    close(connfd);
+                    log_err("epoll add client socket failure, rv=%d\n", rv);
+                }
+                log_dbg("epoll add new client socket[%d] ok.\n", connfd);
+#endif
+            }
+            else 
+            {
+                rv=read(event_array[i].data.fd, buf, sizeof(buf));
+                if( rv <= 0 )
+                {
+                    printf("socket[%d] read failure [%s] or disconncet, close and remove now.\n", 
+                            event_array[i].data.fd, strerror(errno));
+
+                    epoll_del(epollfd, event_array[i].data.fd);
+                    close( event_array[i].data.fd );
+                    continue;
+                }
+                else
+                {
+                    log_dbg("socket[%d] receive %d bytes data\n", event_array[i].data.fd, rv);
+                    logger_dump(LOG_LEVEL_INFO, buf, rv);
+                }
+
+            }
+        }
     }
 
     logger_term();

--
Gitblit v1.9.1