zoukankan      html  css  js  c++  java
  • 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);
    }
  • 相关阅读:
    HTML DOM 12 表格排序
    HTML DOM 10 常用场景
    HTML DOM 10 插入节点
    HTML DOM 09 替换节点
    HTML DOM 08 删除节点
    HTML DOM 07 创建节点
    022 注释
    024 数字类型
    005 基于面向对象设计一个简单的游戏
    021 花式赋值
  • 原文地址:https://www.cnblogs.com/unixshell/p/3824501.html
Copyright © 2011-2022 走看看