0基础学习 IO多路复用(epoll)

#include <sys/epoll.h>
//创建一个新的epoll实例。在内核中创建了一个数据,这个数据中有两个比较重要的数据,一个是需要检测的文件描述符的信息(红黑树),还有一个就绪列表,存放检测到数据发送改变的文件描述符信息(双向链表)。
int epoll_create(int size);
    -参数:
        -size:目前没有意义,随便一个数字,但必须大于0;
    -返回值:
        -1:失败
        >0:文件描述符,操作epoll实例的。
int epoll_ctl(int epfd,int op,int fd,struct epoll_event *event);
    -功能:对epoll实例进行管理;添加文件描述符信息,删除信息,修改信息。
    -参数:
        -epfd:epoll实例对应的文件描述符
        -op:要进行什么操作
            EPOLL_CTL_ADD:添加
            EPOLL_CTL_DEL:删除
            EPOLL_CTL_MOD:修改
        -fd:要检测的文件描述符
        -event:要检测的文件描述符什么事情
struct epoll_event{
    uint32_t events;//Epoll event
    epoll_data_t data;//User data variable
};
常见的Epoll检测事件:
    -EPOLLIN
    -EPOLLOUT
    -EPOLLERR
typedef union epoll_data{
    void *ptr;
    int fd;
    uint32_t u32;
    uint64_t u64;
}epoll_data_t;
int epoll_wait(int epfd,struct epoll_event *events,int maxevents,int timeout);
    -功能:检测函数
    -参数:
        -epfd:epoll实例对应的文件描述符
        -events:传出参数,保存发送变化了的文件描述符的信息
        -maxevents:第二个参数结构体数组的大小
        -timeout:阻塞时间,
            -0:不阻塞
            - -1:阻塞,直到检测到fd数据发生变化时解除阻塞
            - >0:阻塞时长(毫秒)
    -返回值:
        -成功:返回发送变化的文件描述符的个数>0
        -失败:返回-1

 epoll用法三要素:

1、int epfd=epoll_create()系统调用,此调用会返回一个值epfd,之后所有的函数都会使用这个epfd;

工作原理:当某一进程调用epoll_create()时,内核会调用eventpoll结构体,这个结构体中有两个成员与epoll的使用方式密切相关。

struct eventpoll{
    //红黑树的根节点,树中存储着所有添加到epoll中需要监控的事件
    struct rb_root rbr;
    //双链表中则存放着将要通过epoll_wait返回给用户的满足条件的事件
    struct list_head rdlist;
}

2、epoll_ctl(),通过这个调用可以向epoll中添加、删除、修改我们想要的事件,返回0,则成功,返回-1则失败;

3、epoll_wait(),通过此调用收集在epoll监控中已经发生的事件。

#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <sys/epoll.h>
int main()
{
    //1、socket
    int sfd=socket(AF_INET,SOCK_STREAM,0);
    if(lfd==-1)
    {
        perror("socket");
        exit(-1);
    }
    //2、绑定bind
    struct sockaddr_in saddr;
    saddr.sin_family=AF_INET;
    saddr.sin_port=htons(9999);
    saddr.sin_addr.s_addr=INADDR_ANY;
    in bfd=bind(sfd,(struct sockaddr *)&saddr,sizeof(saddr));
    //3、监听listen
    listen(sfd,128);
    //4、创建epoll_wait一个实例
    int epfd=epoll_create(120);
    //将监听得文件描述符相关得检测信息添加到epoll实例中
    struct epoll_event epev;
    epev.events=EPOLLIN;
    epev.data.fd=sfd;
    //对epoll实例进行管理,添加文件描述符信息
    epoll_ctl(epfd,EPOLL_CTL_ADD,sfd,&epev);
    struct epoll_event epevs[1024];
    while(1)
    {
        int ret=epoll_wait(epfd,epevs,1024,-1);
        //返回发送变化的文件描述符的个数
        if(ret==-1)
        {
            perror("epoll_wait");
            exit(-1);
        }
        printf("ret=%d\n",ret);//输出文件描述符的个数
        for(int i=0;i<ret;i++)
        {
            int curfd=epevs[i].data.fd;
            if(curfd==sfd)
            {
                //监听的文件描述符有数据到达,与客户端连接
                struct sockaddr_in cliaddr;
                int len=sizeof(cliaddr);
                int cfd=accept(sfd,(struct sockaddr *)&cliaddr,&len);
                
                epev.events=EPOLLIN;
                epev.data.fd=cfd;
                epoll_ctl(epfd,EPOLL_CTL_ADD,cfd,&epev);
                
            }
            else
            {
                char buf[1024]={0};
                int len=read(curfd,buf,sizeof(buf));
                if(len==-1)
                {
                    perror("read");
                    exit(-1);
                }
                else if(len==0)
                {
                    printf("read closed...\n");
                    epoll_ctl(epfd,EPOLL_CTL_DEL,curfd,NULL);
                    close(curfd);
                }
                else if(len>0)
                {
                    printf("read recv:%s\n",buf);
                    write(curfd,buf,strlen(buf)+1);
                }
            }
        }
    }
    close(cfd);
    close(epfd);
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值