首页 > 代码库 > webserver<2>

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\n", __FILE__, __LINE__);    exit(EXIT_FAILURE);    }while(0)#define err_msg_exit(msg)    do{    perror(msg);    fprintf(stderr, "file %s line %d\n", __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\n");                max_worker--;              break;              }                }else{              int status =0;              if( -1 != wait(&status)){                   //max_worker++;                   fprintf(stderr, "child quit\n");              }                }        }          if(!child){            fprintf(stderr, "before quit, kill all child\n");            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\n");                 }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\n");                   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\n", 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);}