FD_SET的说明如下:
一个long类型的数组,提供给select()机制使用的一种数据结构。主要功能是建立联系。
其中每一个数组元素都能与任意一个打开的句柄(socket句柄、文件、命名管道、设备句柄等)建立联系。但是这种建立联系的工作是必须由程序员自己去完成的。
下面实现C++代码,看代码中的注释即可。
#include <sys/select.h>
//定义两个宏,用于将文件描述符数量乘以或除以字的大小 (即一个fd_set的fds_bits数组中的一个元素代表32个文件描述符)
#define ACE_DIV_BY_WORDSIZE(x) ((x) / 32)
#define ACE_MULT_BY_WORDSIZE(x) ((x) * 32)
class FdSetManager
{
public:
FdSetManager() // 构造函数,初始化fd_set和最大文件描述符变量
{
FD_ZERO(&set);
maxFd = -1;
}
~FdSetManager() {}
void add(int fd) // 向fd_set中添加一个文件描述符 更新最大文件描述符
{
if (fd < 0) {
return;
}
if (fd > maxFd) {
maxFd = fd;
}
FD_SET(fd, &set);
}
void remove(int fd) // 从fd_set中移除一个文件描述符
{
if (fd < 0) {
return;
}
FD_CLR(fd, &set);
//如果移除的为最大是句柄
if (fd == maxFd) {
int i;
// 从最大文件描述符对应的数组索引开始,向上遍历直到找到第一个非零的fds_bits元素
for (i = ACE_DIV_BY_WORDSIZE(maxFd - 1); set.fds_bits[i] == 0 && i >= 0; i--)
continue;
// 如果i小于0,说明所有位都是0,即没有文件描述符被设置
if (i < 0) {
maxFd = -1;
} else {
// 否则,找到非零的fds_bits元素,计算新的最大文件描述符
maxFd = ACE_MULT_BY_WORDSIZE(i);
// 然后在该元素的位掩码中,从最低位开始,找到第一个被设置的位(即最后一个被设置的文件描述符)
for (fd_mask val = set.fds_bits[i]; (val & ~1) != 0; val = (val >> 1)) {
// 每找到一个被设置的位,就将maxFd加1
++maxFd;
}
}
}
}
bool contains(int fd) // 判断fd_set中是否包含某个文件描述符
{
if (fd < 0) {
return false;
}
return FD_ISSET(fd, &set);
}
fd_set& getSet() // 获取fd_set的引用
{
return set;
}
int getMaxfd() // 获取当前记录的最大文件描述符+1(因为select等系统调用需要这样传递)
{
return maxFd + 1;
}
private:
fd_set set; // 用于存储文件描述符集合
int maxFd; // 记录当前fd_set中最大的文件描述符
};
以上代码为自己项目中的实现,可以根据自己的想法来实现,仅供参考。