• webserver<2>


    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <sys/socket.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <string.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <sys/epoll.h>
    #include <errno.h>
    #include "common.h"
    #include "serversignal.h"
    #include "server_epoll.h"
    
    static int open_socket(struct sockaddr_in* paddr);
    static int accept_client(int sockfd, struct sockaddr_in* paddr);
    
    static int process_request(int connfd);
    static volatile sig_atomic_t graceful=0;
    
    #define HTTP_PORT 18080
    #define BACK_LOG  50
    #define MAX_FDS   100
    #define SOCKLEN   sizeof(struct sockaddr_in)
    
    #define err_log_exit()
        do{
        perror("server failed");
        fprintf(stderr, "file %s line %d
    ", __FILE__, __LINE__);
        exit(EXIT_FAILURE);
        }while(0)
    
    
    #define err_msg_exit(msg)
        do{
        perror(msg);
        fprintf(stderr, "file %s line %d
    ", __FILE__, __LINE__);
        exit(EXIT_FAILURE);
        }while(0)
    
    static int setnonblocking(int sockfd)
    {
            if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1)
            {
                return -1;
            }
    
            return 0;
    }
    
    int main(int argc, char *argv[])
    {
                signal_init();
            int max_worker = 2;
                int child = 0;
            int epollfd = 0; 
            struct sockaddr_in      saddr;
                int sockfd = 0;
            int nfds   = 0;
            int index  = 0;
            int fd = 0;
            int acceptfd = 0;
            struct epoll_event *events;
            
            memset(&saddr, 0, sizeof(struct sockaddr_in));        
            
            sockfd=open_socket(&saddr);
            
            if(sockfd == -1)
                    err_log_exit();
    
                while(!graceful&&!child){
                    if(max_worker>0){
                      switch(fork()){
                      case -1:
                    err_log_exit();
                  break;
                          case 0:
                    child =1;
                  break;
                  default:
                    printf("child creat
    ");
                    max_worker--;
                  break;
                  }
                    }else{
                  int status =0;
                  if( -1 != wait(&status)){
                       //max_worker++;
                       fprintf(stderr, "child quit
    ");
                  }
                    }
            }
     
             if(!child){
                fprintf(stderr, "before quit, kill all child
    ");
                kill(0, SIGINT);
                sleep(2); 
                return 0;
                }
            
            //child
            epollfd = server_epoll_create(MAX_FDS+1);
            if(epollfd == -1)
            err_log_exit();
    
            if(server_epoll_event_add(epollfd, sockfd) == -1)
            err_log_exit();
        
            events = (struct epoll_event*)malloc(MAX_FDS*sizeof(struct epoll_event));
            memset(events, 0, MAX_FDS*sizeof(struct epoll_event));
            
            /* close stdin and stdout, as they are not needed */
            /* move stdin to /dev/null */
            if (-1 != (fd = open("/dev/null", O_RDONLY))) {
                close(STDIN_FILENO);
            dup2(fd, STDIN_FILENO);
            close(fd);
            }
    
           /* move stdout to /dev/null */
           if (-1 != (fd = open("/dev/null", O_WRONLY))) {
             close(STDOUT_FILENO);
                dup2(fd, STDOUT_FILENO);
            close(fd);
           }
    
           while(child&&!graceful){
            nfds = epoll_wait(epollfd, events, MAX_FDS, 500);            
            index = 0;
                
            while(index < nfds){
                  
                 if(events[index].data.fd == sockfd){
                  acceptfd = accept_client(sockfd, &saddr);
                  //waking herd
                  if(acceptfd == -1){
                      perror("accept failed
    ");   
                  }else{
                      //accept ok
                      if(server_epoll_event_add(epollfd, acceptfd) == -1)
                       err_log_exit();
                  }
                  }else if(events[index].data.fd == acceptfd){
                  // receive data from client
                  // if client close, need avoid TIME_WAIT status
                  if(process_request(acceptfd) == 0){
                       fprintf(stderr, "client close, close connection and quit listen connect fd
    ");
                       if(server_epoll_event_del(epollfd, acceptfd) == -1)
                            err_log_exit(); 
                       close(acceptfd);
                  }
                  }else{
                  
                  }
                  index++; 
            };    
            
            if(nfds == -1){
                if (errno == EINTR)
                    continue;
                else{
                    err_log_exit();
                }
            }
    
            };
            
            return 0;
    }
    
    void server_graceful_set(int g)
    {
        if(g>0){
            g=1;
        }else{
            g=0;
        }
        graceful=g;
    }
    
    int server_graceful_get()
    {
        return graceful;
    }
    
    
    static int open_socket(struct sockaddr_in* paddr)
    {
        int      sockfd         = 0;
        struct  sockaddr_in     sockaddress;
        
        bzero(&sockaddress, sizeof(sockaddress));
        
        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
                        err_log_exit();
    
        sockaddress.sin_family = AF_INET;
        sockaddress.sin_port   = htons(HTTP_PORT);    
        
        setnonblocking(sockfd);
        
        inet_pton(AF_INET, "10.174.8.163", &(sockaddress.sin_addr));
        
        if(bind(sockfd, (struct sockaddr*)(&sockaddress), sizeof(sockaddress)) == -1)
                        err_log_exit();
        
        if(listen(sockfd, BACK_LOG) == -1)
                        err_log_exit();
        
        *paddr = sockaddress;
        return sockfd;
    }
    
    static int accept_client(int sockfd, struct sockaddr_in* paddr)
    {
        socklen_t len         = SOCKLEN;
        int       connfd    = 0;
    
        if(paddr != NULL)
        {    
            connfd = accept(sockfd, (struct sockaddr*)(paddr), &len);
        }else
        {
            connfd = -1;
        }
        return connfd;    
    }
    
    static int process_request(int connfd)
    {
        char request[1000];
        int len = 0;
        bzero(request, sizeof(request));
        len = recv(connfd, request, sizeof(request), 0);
        if(len >0)
            fprintf(stderr, "%s
    ", request);
        
        return len;
    }
    #include <unistd.h>
    #include <string.h>
    #include "server_epoll.h"
    
    int server_epoll_event_add(int epollfd, int sockfd)
    {    
        struct epoll_event ep;
        memset(&ep, 0, sizeof(ep));
        ep.events = 0;
        ep.events |= EPOLLIN;
        ep.events |= EPOLLOUT;
        ep.data.fd = sockfd;    
    
        return epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &ep);
    }
    
    int server_epoll_event_del(int epollfd, int sockfd)
    {    
        struct epoll_event ep;
        memset(&ep, 0, sizeof(ep));
        ep.events = 0;
        ep.events |= EPOLLIN;
        ep.events |= EPOLLOUT;
        ep.data.fd = sockfd;    
    
        return epoll_ctl(epollfd, EPOLL_CTL_DEL, sockfd, &ep);
    }
    
    int server_epoll_create(int size)
    {
        int fd = epoll_create(size);
        return fd;    
    }
    
    int server_epoll_close(int fd)
    {
        return close(fd);
    }
  • 相关阅读:
    c#无边框窗体移动 屏蔽双击最大化
    怎么样让代码都带有注释?
    权限设置相关,利用Microsoft.Win32.Security
    计算几何常用算法概览[转]
    VS 常见快捷键
    关于读取txt文件的分段问题
    ajax 常用方法
    文件以附件形式下载的方法
    半角和全角互换
    在ubuntu 中安装 jsdoc
  • 原文地址:https://www.cnblogs.com/unixshell/p/3824501.html
Copyright © 2020-2023  润新知