zoukankan      html  css  js  c++  java
  • epoll反应堆模型代码

    libevent函数库核心思想

    /***
    epoll_loop.c
    ***/
    #include<stdio.h>
    #include<sys/epoll.h>
    #include<sys/socket.h>
    #include<arpa/inet.h>
    #include<fcntl.h>
    #include<unistd.h>
    #include<errno.h>
    #include<string.h>
    #include<stdlib.h>
    #include<time.h>
    
    #define MAX_EVENTS 2014
    #define BUFLEN 4096
    #define SERV_PORT 8080
    
    void recvdata(int fd,int events,void *arg);
    void senddata(int fd,int events,void *arg);
    
    struct myevent_s
    {
        int fd;
        int events;
        void *arg;
        void (*call_back)(int fd,int events,void *arg);
        int status;
        char buf[BUFLEN];
        int len;
        long last_active;
    };
    
    int g_efd;
    struct myevent_s g_events[MAX_EVENTS + 1];
    
    void eventset(struct myevent_s *ev,int fd,void (*call_back)(int,int,void*),void *arg)
    {
        ev->fd = fd;
        ev->call_back = call_back;
        ev->events = 0;
        ev->arg = arg;
        ev->status = 0;
        ev->last_active = time(NULL);
        return;
    }
    
    void eventadd(int efd,int events,struct myevent_s *ev)
    {
        struct epoll_event epv = {0,{0}};
        int op;
        epv.data.ptr = ev;
        epv.events = ev->events = events;
    
        if(ev->status == 1)
        {
            op = EPOLL_CTL_MOD; 
        }
        else
        {
            op = EPOLL_CTL_ADD;
            ev->status = 1; 
        }
    
        if(epoll_ctl(efd,op,ev->fd,&epv) < 0)
        {
            printf("event add failed [fd=%d],evens[%d]
    ",ev->fd,events) ;
        }
        else
        {
            printf("event add OK[fd=%d],op = %d,evens[%0X]
    ",ev->fd,op,events) ;
             
        }
        return;
    }
    
    void eventdel(int efd,struct myevent_s *ev)
    {
        struct epoll_event epv = {0,{0}};
    
        if(ev->status != 1)
        {
            return; 
        }
    
        epv.data.ptr = ev;
        ev->status = 0;
        epoll_ctl(efd,EPOLL_CTL_DEL,ev->fd,&epv);
    
        return;
    }
    
    
    void acceptconn(int lfd,int events,void *arg)
    {
        struct sockaddr_in cin;
        socklen_t len = sizeof(cin);
        int cfd,i;
    
        if((cfd = accept(lfd,(struct sockaddr *)&cin,&len)) == -1)
        {
            if(errno != EAGAIN && errno != EINTR) 
            {
            
            }
            printf("%s : accept,%s 
    ",__func__,strerror(errno));
            return ;
        }
    
        do
        {
            for(i = 0; i < MAX_EVENTS; i++) 
            {
                if(g_events[i].status == 0) 
                {
                    break; 
                }
            }
                
                if(i == MAX_EVENTS)
                {
                    printf("%s: max connect limit[%d]
    ]",__func__,MAX_EVENTS) ;
                    return;
                }
    
                int flag = 0;
                if((flag = fcntl(cfd,F_SETFL,O_NONBLOCK)) < 0)
                {
                     printf("%s : accept,%s 
    ",__func__,strerror(errno));
                     break;
                }
    
                eventset(&g_events[i],cfd,recvdata,&g_events[i]);
                eventadd(g_efd,EPOLLIN,&g_events[i]);
        }while(0);
    
        printf("new connect [%s:%d][time:%ld],pos[%d]
    ",
                inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),g_events[i].last_active,i);
        return;
    }
    
    void recvdata(int fd,int events,void *arg)
    {
        struct myevent_s *ev = (struct myevent_s *)arg;
        int len;
    
        len = recv(fd,ev->buf,sizeof(ev->buf),0);
    
        eventdel(g_efd,ev);
    
        if(len > 0)
        {
            ev->len = len;
            ev->buf[len]  = 0;
            printf("C[%d]:%s
    ",fd,ev->buf);
            
            eventset(ev,fd,senddata,ev);
            eventadd(g_efd,EPOLLOUT,ev);
        }
        else if(len == 0)
        {
            close(ev->fd) ;
            printf("[fd = %d] pos[%ld],close
    ",fd,ev-g_events);
        }
        else
        {
            close(ev->fd) ;
            printf("recv[fd=%d] error[%d]:%s
    ",fd,errno,strerror(errno));
        }
        return;
    }
    
    void senddata(int fd,int events,void *arg)
    {
        struct myevent_s *ev = (struct myevent_s *)arg;
        int len;
    
        len = send(fd,ev->buf,ev->len,0);
    
        if(len > 0)
        {
            printf("send[fd=%d],[%d]%s
    ",fd,len,ev->buf) ;
            eventdel(g_efd,ev);
            eventset(ev,fd,recvdata,ev);
            eventadd(g_efd,EPOLLIN,ev);
        }
        else
        {
            close(ev->fd) ;
            eventdel(g_efd,ev);
            printf("send[fd=%d] error %s
    ",fd,strerror(errno));
        }
        return;
    }
    
    void initlistensocket(int efd,short port)
    {
        int lfd = socket(AF_INET,SOCK_STREAM,0);
        fcntl(lfd,F_SETFL,O_NONBLOCK);
    
        eventset(&g_events[MAX_EVENTS],lfd,acceptconn,&g_events[MAX_EVENTS]);
        eventadd(efd,EPOLLIN,&g_events[MAX_EVENTS]);
    
        struct sockaddr_in sin;
        memset(&sin,0,sizeof(sin));
        sin.sin_addr.s_addr = INADDR_ANY;
        sin.sin_family = AF_INET;
        sin.sin_port = htons(port);
    
        bind(lfd,(struct sockaddr*)&sin,sizeof(sin));
        listen(lfd,20);
        return ;
    }
    
    
    int main(int argc, char *argv[])
    {
        unsigned short port = SERV_PORT;
    
        if(argc == 2)
        {
            port = atoi(argv[1]) ;
        }
    
        g_efd = epoll_create(MAX_EVENTS+1);
        if(g_efd <= 0)
        {
            printf("Create efd in %s error %s
    ",
                    __func__,strerror(errno)) ;
        }
        initlistensocket(g_efd,port);
    
        struct epoll_event events[MAX_EVENTS+1];
        printf("server running:port[%d]
    ",port);
    
        int checkpos = 0,i;
        while(1)
        {
            long now = time(NULL) ;
            for(i = 0 ; i < 100; i++,checkpos++)
            {
                if(checkpos == MAX_EVENTS) 
                    checkpos = 0;
                if(g_events[checkpos].status != 1)
                {
                    continue; 
                }
    
                long duration = now - g_events[checkpos].last_active;
    
                if(duration >= 60)
                {
                    close(g_events[checkpos].fd) ;
                    printf("[fd=%d] timeout
    ",g_events[checkpos].fd);
                    eventdel(g_efd,&g_events[checkpos]);
                }
            }
    
            int nfd = epoll_wait(g_efd,events,MAX_EVENTS+1,1000);
            if(nfd < 0)
            {
                printf("epoll_wait error, exit
    ") ;
                break;
            }
    
            for(i = 0; i < nfd; i++)
            {
                struct myevent_s *ev = (struct myevent_s *)events[i].data.ptr;
    
                if((events[i].events & EPOLLIN) && (ev->events & EPOLLIN))
                {
                    ev->call_back(ev->fd,events[i].events,ev->arg) ;
                }
                if((events[i].events & EPOLLOUT) && (ev->events & EPOLLOUT))
                {
                    ev->call_back(ev->fd,events[i].events,ev->arg);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    《代码整洁之道》三
    《代码整洁之道》二
    第五周总结
    第四周总结
    第三周总结
    第二周总结
    第一周总结
    课程总结
    周总结16
    河北省科技信息通用调查系统综合查询功能开发——Day9
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11443231.html
Copyright © 2011-2022 走看看