当前位置: 代码迷 >> 综合 >> select 和 epoll
  详细解决方案

select 和 epoll

热度:87   发布时间:2023-12-16 23:20:02.0

select:

int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

nfds: 当前所有集合中最大的描述符值
readfds:探测可读描述符集合
writefds:探测可写描述符集合
exceptfds:探测异常描述符集合
timeout:等待超时时间,0–>非阻塞,NULL–>永久阻塞

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);清空集合
优点:可移植性较强
缺点:(1)、监听描述符有上限个数1024(可以修改头文件,但需要重编译内核)(2)、需要定义数组保存所有描述符值,以便每次在新连接到来或者有旧连接关闭时,可以重新确定最大的描述符的值(3)、每次处理完毕后,需要清空并重新向集合中添加描述符(因为select描述符状态的改变是直接在原有基础上改变的,因此需要每次情况)(4)、当有就绪描述符时,select并不会告诉我们哪一个描述符已经就绪,指示在原有集合上修改状态,因此当我们处理的时候,需要循环便利集合中的所有描述符才能判断哪一个是就绪描述符---(当监听数目过大时,效率较低)
1、创建socket。
2、定义监听地址信息,并为socket绑定监听地址。
3、开始监听。(告诉系统开始监听地址是否有数据到来)
4、将socket描述符添加到select的监听集合。(监听集合用于select监听到判断集合中的描述符是否就绪)
5、select开始监听
6、seletc返回值<0 出错=0 等待超时(指定时间内没有就绪的描述符)>0 已经有描述符就绪
7、当描述符就绪,判断描述符是否等于监听socket描述符(代表由新的连接请求)a.=监听socket描述符(accept处理新的连接器请求),确定当前最大描述符的值。b.!=监听描述符(代表有传输数据到来),接收数据。c.接受出错,将描述符从select监听集合中删除,并关闭,重新确定最大描述符值。
8、关闭描述符

epoll:
1、创建socket
2、定义监听地址信息,并为socket绑定监听地址
3、开始监听(告诉系统开始监听地址是否有数据到来)
4、创建epoll监听集合
5、定义事件结构,并将事件与描述符关联
6、将描述符与事件添加到epoll监听集合
7、开始epoll监听(返回值判断)
a.<0 epoll_wait错误
b.=0 epoll_wait超时
c.>0 就绪的时间个数,将已经就绪的时间放到一个指定的事件数组中,
8、根据就绪的事件个数,循环遍历就绪事件数组
a.判断事件fd是否=监听描述符
== 处理新连接
!= 其他的数据传输事件
b.传输若出错,则将描述符从epoll监听集合中删除,并关闭
9、关闭

  相关解决方案