网络编程:IO多路复用(select、poll、epoll)

1. 创建文件描述符集合

2. 将关注的文件描述符添加到集合

3. 将文件描述符传递给内核,内核开始检测IO事件

4. 内核返回到达事件的结果

select

特点:

        1. 使用数组(位图)保存文件描述符集合,最多允许监测1024个文件描述符;

        2. 将集合表创建在应用层,存在应用层和内核层数据的反复拷贝;

        3. 事件到达时,内核返回整个集合表,应用层需要遍历;

        4. select只能工作在水平触发模式(低速模式),不能工作在边沿触发模式(高速模式);

1. 创建文件描述符集合(位图(数组)--1024

fd_set fds;

FD_ZERO(&fds);

2. 将要监测的文件描述符加入集合

FD_SET(fd, &fds);

3. 将集合传递给内核开始监测IO事件,并且返回监测的结果

int select(int nfds, fd_set *readfds, fd_set *writefds,

                fd_set *exceptfds, struct timeval *timeout);

功能:将文件描述符传递给内核开始监测IO事件,并返回监测到的结果

参数:

        nfds:监测的文件描述符最大值+1

        readfds:要监测的读事件的文件描述符集合

        writefds:要监测的写事件的文件描述符集合

        exceptfds:要监测的出错事件的文件描述符集合

        timeout:超时时间

        NULL :不设置超时时间:阻塞等到

返回值:

        成功:实际到达的IO事件的个数

        失败:-1

        0 :设置超时事件,超时时间到没有事件到达

                        void FD_CLR(int fd, fd_set *set);

                        int FD_ISSET(int fd, fd_set *set);

                        void FD_SET(int fd, fd_set *set);

                        void FD_ZERO(fd_set *set);

int sockfd = socket();
bind();
listen();
//sockfd-->rdfds
while (1)
{
    select(rdfds);
    if (FD_ISSET(sockfd))
    {
    int connfd = accept();
        //connfd --->rdfds
    }
    for (i = sockfd+1; i <= maxfd; ++i)
    {
        if (FD_ISSET(i))
        {
            recv();
            send();
        }
    }
}

poll

特点:

        1. 使用链表保存文件描述符集合,允许监测的文件描述符没有上限限制;

        2. 创建的文件描述符集合在应用层,需要应用层和内核层的反复数据拷贝;

        3. 应用层对于返回的事件结果需要遍历查找;

        4. poll只能工作在水平触发模式(低速模式),无法工作在边沿触发模式(高速模式)。

epoll

特点:

        1. 使用树形结构(红黑树)保存文件描述符集合,没有文件描述符上限限制,并且查找效率高;

        2. 文件描述符集合创建在内核层,避免了应用层和内核层的反复数据拷贝;

        3. 直接返回到达事件的文件描述符集合;

        4. epoll可以工作在水平触发模式(低速模式),也可以工作在边沿触发模式(高速模式);

1. 创建文件描述符集合

int epoll_create(int size);

功能:创建epoll的文件描述符集合

参数:

        size :允许监测的文件描述符的个数

返回值:

        成功:返回文件描述符句柄。

        失败:-1

2. 添加文件描述符到集合

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

功能:对文件描述符集合中的文件描述符做操作

参数:

        epfd:epoll创建的文件描述符集合

        op:操作方法:

                EPOLL_CTL_ADD :添加操作

                EPOLL_CTL_MOD :修改操作

                EPOLL_CTL_DEL :删除操作

        fd :要操作的文件描述符

        event:epoll事件结构体

                        typedef union epoll_data {

                                        void *ptr;

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

                                        uint32_t u32;

                                        uint64_t u64;

                                      } epoll_data_t;

struct epoll_event {

                                uint32_t events; /* Epoll events */

                                epoll_data_t data; /* User data variable */

};

                events:事件类型

                                EPOLLIN: 读事件

                                EPOLLOUT :写事件

返回值:

                成功:0

                失败:-1

3. 通知内核开始监测事件

int epoll_wait(int epfd, struct epoll_event *events,

                        int maxevents, int timeout);

功能:通知内核开始监测事件

参数:

        epfd:监测的文件描述符句柄

        events :保存epoll返回的到达事件的集合

        maxevents:最多监测的事件个数

        timeout:设置超时时间

                        -1 :不设置超时,一直阻塞等待

返回值:

        成功:实际到达的事件的个数

        失败:-1

        0 :超时时间到达,却没有事件返回时

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值