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));

                        }

                    }
        
                }

        }

    }

//处理

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LuckyDog0623

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值