欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2020-11-29 epoll函数的基本使用过程

程序员文章站 2022-03-14 13:51:50
...

 

 

2020-11-29 epoll函数的基本使用过程

一般用于服务器监听某一个文件描述符;和select相似

 

1、创建红黑树,用于监听文件描述符

#include <sys/epoll.h>

int epoll_create(int size)

功能:创建红黑树

参数:size:写大于0即可

返回值:数的句柄

 

2、节点上树、节点下树、修改树节点

#include <sys/epoll.h>

int epoll_ctl(int efd,int op,int fd,struct epoll_event *event)

功能:

参数:epfd:树的根节点(句柄)

op:

EPOLL_CTL_ADD

EPOLL_CTL_MOD

EPOLL_CTL_DEL

fd:需要上树监听的文件描述符

event:一个树上的节点,

 

typedef union epoll_data{

      void *ptr;

      int fd;//需要监听的文件描述符

      unit32_t u32;

      unit64_t u64;

}epoll_data_t;

 

struct epoll_event{

      unit32_t events;

      epoll_data_t data;

}这是一个上下树节点的全部信息,包括事件和文件描述符;

于是用户态定义接收的数组也应该是这种类型的结构体

events:可以选择的事件有很多,包括写读什么的;

EPOLLIN写事件;

EPOLLOUT读事件;

返回值:成功返回0,失败返回1

 

3、监听

#include <sys/epoll.h>

int epoll_wait(int efd, srtuct epoll_event *ev,int maxevent,int timeout)

功能:

参数:

epfd 树的根节点

ev:用于接收树变化struct epoll_event数组元素首地址

maxevent:数组元素的个数

timeout:-1永久监听;>0限时间

返回值:变化文件描述符的个数

 

使用案例:

int main(int argc, char **argv)

{
    //1、创建套接字

    //2、绑定

    int lfd = tcp4bind(7777,NULL);

    //3、监听

    listen(lfd, 128);

    //创建树

    int epfd=epoll_create(1);

    //将lfd上树

     struct epoll_event ev;

     ev.events=EPOLLIN; //读事件

     ev.data.fd=lfd;

     epoll_ctl(epfd, EPOLL_CTL_ADD,lfd, &ev)

    //循环监听树

    while(1)

    {

        struct epoll_event evs[1024]; //用户态创建的用于监听文件描述符

        int n = epoll_wait(epfd, evs, 1024, -1);

        if(n<0) perror("");

        else if(n>=0)

        {

            for(int i=0; i<n; i++)

                {

                    int fd= evs[i].data.fd;

                    if(fd == lfd && evs[i].events&EPOLLIN) //返回的事件位与读事件

                    //如果位与是非0值就代表产生了读事件

                    {

                        struct sockaddr_in cliaaddr;

                        socklen_t len=sizeof(cliaddr);

                        char ip[16]=" ";
    
                        int cfd=Accept(lfd, (struct sockaddr*)&cliaddr, &len);
        
                                printf("client ip=%s, port=%d\n",
    
                                inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr, ip, 16),

                                ntohs(cliaddr.sin_port));

                        //将cfd上树

                        ev.events=EPOLLIN; //读事件

                        ev.data.fd=cfd;

                        epoll_ctl(epfd, EPOLL_CTL_ADD,cfd, &ev)

                    }
    
                    else if(fd == lfd && evs[i].events&EPOLLOUT) 同理写事件

                    {

                        char buf[1500]=" ";

                        int count = read(fd, buf, sizeof(buf));

                        if(count <=0)

                        {

                            perror("");

                            //下树关闭文件描述符

                            ...
        
                        }

                        else

                        {

                            write(fd,buf, sizeof(buf));

                        }

                    }
        
                }

        }

    }

//处理

}

 

相关标签: epoll