socket多路IO复用之select模型

马谦马谦马谦 2018年4月9日11:31:03 发表评论
文章最后编辑于:2018-5-4 22:54:09

select模型是socket中的一种多路IO复用模型之一,通过轮询的方式来完成多路访问控制。

一个很简单的例子来描述select模型:

幼儿园老师要照顾所有的小朋友,每天他都会轮流去问小朋友:“小朋友小朋友,你饿了吗?”

如果小朋友饿了,那么老师就给这个小朋友喂饭,否则就开始询问下一个朋友,一直循环下去直到放学。

同时,如果班级里有其他的同学来了,也把他加到询问队列。如果有哪个同学生病了,则把它踢出询问队列。

select模型的原理就是这样,把所有连接的客户端socket加入到一个集合中去,然后一直不断轮询,判断哪一个socket有数据到达,就读取数据。否则继续轮询下一个数据。

linux系统在编译的时候就固定了select模型文件描述符集合的大小为1024个,这个大小无法更改,因此,select模型只适用于并发量小于1024个的服务连接。

一、相关函数

select用来判断文件描述符结合中是否有文件描述符发生了相应的事件,如果有事件则返回(这个策略可以改变)。

参数说明:

nfds: 监控的文件描述符集里最大文件描述符加1,因为此参数会告诉内核检测前多少个文件描述符的状态。

readfds:监控有读数据到达文件描述符集合,传入传出参数。

writefds:监控写数据到达文件描述符集合,传入传出参数。

exceptfds:监控异常发生达文件描述符集合,如带外数据到达异常,传入传出参数。

timeout:定时阻塞监控时间,3种情况:1.NULL,永远等下去;2.设置timeval,等待固定时间;3.设置timeval里时间均为0,检查描述字后立即返回

返回值: 文件描述符集合中有响应时间的文件描述符个数。

超时类型的结构体:

对监控描述符集合的操作:

通常情况下,我们需要一个客户端数组保存每一个客户端的状态,表示当前集合中的该元素是否已经有存在或者连接。然后还要有一个最大的文件描述符标志,用来轮询。

一旦select返回,我们要先判断是否为服务端的socket,如果是服务端的,说明有新的连接加入,把这个新连接加入到集合中去。否则则说明是客户端连接有响应,这时候需要一个一个去循环判断,看哪个socket有数据到达,然后处理。

二、示例代码

本文共执行44次查询,耗时0.272秒!
马谦马谦马谦

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: