windows网络编程之Select模型基础知识

时间:2022-12-17 22:22:55

网络编程之Select模型
一. 设计思想:
利用select函数,判断套接字上是否存在数据,或者能否向一个套接字写入数据。目的是防止应用程序在套接字处于锁定模式时,调用recv(或send)从没有数据的套接字上接收数据,*进入阻塞状态。

二. Select函数:
2.1 select函数

int select (
int nfds, //忽略,仅为了与Berkeley套接字兼容
fd_set FAR * readfds, //指向一个套接字集合,用来检测其可读性
fd_set FAR * writefds, //指向一个套接字集合,用来检测器可写性
fd_set FAR * exceptfds, //指向一个套接字集合,用来检测错误
const struct timeval FAR * timeout //等待函数最长时间,NULL为无限大
);
//返回值,函数调用成功,返回网络事件的所有套接字数量的总和,
// 超时返回0
// 失败返回SOCKET_ERROR
2.2 套接字集合:
fd_set结构可以把多个套接字连接到一起,形成套接字集合,select函数可以测试这个集合中那些套接字发生了网络事件。
typedef struct fd_set{
    u_int fd_count;                 //套接字数组大小
SOCKET fd_array[FD_SETSIZE]; //套接字数据
}fd_set;

//fd_set套接字金额和相关的宏:
FD_ZERO(*set) //初始化set为空集合。集合使用前应该初始化为空
FD_CLR(s, *set) //从set中移除套接字s
FD_ISSET(s, *set) //判断s是否是set的成员,返回一个BOOL值
FD_SET(s, *set) //将套接字s添加到集合set中
2.3 网络事件
传递给select函数的3个fd_set结构中,
readfds: 为了检查其可读性对应的网络事件:
1. 数据可读(接收到数据)
2. 连接已经关闭,重启或者中断
3. 监听套接字接收到客户端连接,accept将成功

writefds:为了检查可写性,对应的网络事件:
1. 数据能够发送
2. 如果一个非阻塞套接字连接调用正在处理,连接已成功(客户端调用connect函数)

exceptfds:检查错误,对应的网络事件:
1. 连接失败
2. OOB数据可读

注意:
select中任何两个集合都可以为空,非空的集合至少含有一个套接字。

使用说明:
当select函数返回时,他通过移除没有未决I/O操作的套接字句柄,改变每个fd_set集合
例如:想要测试套接字s是否可读的步骤:
1. 将s添加到readfds集合,调用select函数,等待返回。
2. 返回,确定s是否还在select函数中,
在:调用recv或者accept函数接收信息
否则:返回