在之前的版本(1.1和1.2)中,服务端和客户端都是1对1的阻塞模型网络程序,例如服务端的accept,recv都是阻塞等待。一个最大的问题是,当服务端阻塞时,不能处理其它的业务,从而无法实现一个服务端处理多个客户端的功能。因此,将服务端升级为Select模型处理多客户端的网络请求。
Select网络模型是Linux、Windows、IOS、安卓等操作系统中标准C/C++支持的网络通信模型,内部会定时查询是否有新的客户端连接/新的业务需要处理,从而做出相应的处理。掌握了Select网络模型,便可以支持编写中、小型的网络程序。
Socket Select网络模型在Windows下面的定义
select(
_In_ int nfds, //在windows下面没有意义 在Unix衍生的操作系统中使用
_Inout_opt_ fd_set FAR * readfds, //_Inout_ 表示这个参数传入时是有意义的 传出时也是有意义的 指向检查可读性的套接字集合的可选的指针。表示客户端有读的socket客户端需求等待处理
_Inout_opt_ fd_set FAR * writefds, //指向检查可写性的套接字集合的可选的指针。表示客户端有写的socket客户端需求等待处理
_Inout_opt_ fd_set FAR * exceptfds, //指向检查错误的套接字集合的可选的指针。表示客户端有异常的Socket客户端的需求等待处理
_In_opt_ const struct timeval FAR * timeout //函数需要等待的最长时间,需要以TIMEVAL结构体格式提供此参数,对于阻塞操作,此参数为null。
);
select函数的理解:(转载自https://www.cnblogs.com/zxllm/p/5420065.html)
select函数用于决定一个或者多个socket的状态。对于每一个socket,客户端可以请求读、写或者错误状态信息。一个请求给定状态的socket集由fd_set结构体指定。在fd_set结构体中的socket必须和单个服务端联系在一起。select函数返回满足条件的套接字个数。fd_set集合可以通过一些宏手动操作。
(1)参数readfds指示检查socket的可读性。当socket在listen状态(服务端socket),如果已经接收一个连接请求,这个socket会被标记为可读,例如一个accept会确保不会阻塞的完成。对于其他的socket(客户端socket),可读性意味着队列中的数据