查看 fd_set 定义的所在文件
vim /usr/include/linux/posix_types.h
发现 __FD_SETSIZE 没有办法被重新定义,undef是解除存在的定义,
不允许修改宏来修改fd_set的大小
#undef __FD_SETSIZE
#define __FD_SETSIZE 1024
typedef struct {
unsigned long fds_bits[__FD_SETSIZE / (8 * sizeof(long))];
} __kernel_fd_set;
__FD_SETSIZE / (8 * sizeof(long)); // 1024/64=16,数组大小16个(0-15)
一个long 8字节,一个字节8位,总的占64位。
64*16=1024 ,总的1024位 ,128字节
Linux的fd_set是按位存储的。
如果socket为4,那么 (4除以8,商为0,余数为4),所以socket放在第一个字节(下标为0)的第4个比特位的位置上。
如果socket为17,那么 (17除以8,商为2,余数为1),所以socket放在第三个字节(下标为2)的第1个比特位的位置上。
如果socket为1024,那么 (1024除以8,商为128,余数为0),所以socket放在第129个字节(下标为128)的第1个比特位的位置上。但是下标为数组的字节下标范围是0-127,明显数组越界了,无法存放1024个。(128/8=16,数组下标为0-15,越界了)
突破select 1024
#ifndef _CELL_THREAD_HPP
#define _CELL_THREAD_HPP
#include<unistd.h> //uni std
#include<arpa/inet.h>
#include<string.h>
#include<signal.h>
#define SOCKET int
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
//#define CELL_MAX_FD 10240
#define FD_SETSIZE 10240
class CELLFDSet
{
public:
CELLFDSet()
{
//socket的数量
int nSocketNum = FD_SETSIZE ; //10240;// FD_SETSIZE
//要申请的内存大小
#ifdef _WIN32
//window的fdset结构:
// typedef struct fd_set {
// u_int fd_count; /* how many are SET? */
// SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */
// } fd_set;
_nfdSize = sizeof(u_int) + ( sizeof(SOCKET)*nSocketNum );
#else
//Linux的fdset结构:
// typedef struct {
// unsigned long fds_bits[__FD_SETSIZE / (8 * sizeof(long))];
// } __kernel_fd_set;
//long
_nfdSize = nSocketNum /(8*sizeof(char)); //下面用的是char申请,所以用char
#endif
//创建动态内存
_pfdset =(fd_set *) new char[_nfdSize];
memset(_pfdset, 0, _nfdSize);
}
inline void add(SOCKET sock)
{
#ifdef _WIN32
FD_SET(sock, _pfdset); //里面使用到 FD_SETSIZE ,所以FD_SETSIZE 是一定要定义的
#else
if (sock < FD_SETSIZE) // CELL_MAX_FD
{
FD_SET(sock, _pfdset);
}
else
{
printf("Error, FD_SET sock fail");
}
#endif // !_WIN32
}
inline void del(SOCKET s)
{
FD_CLR(s,_pfdset);
}
void zero()
{
#ifdef _WIN32
FD_ZERO(_pfdset);
#else
memset(_pfdset, 0, _nfdSize);
#endif
}
inline bool has(SOCKET s)
{
return FD_ISSET(s,_pfdset);
}
inline fd_set* fdset()
{
return _pfdset;
}
void copy(CELLFDSet& set)
{
memcpy(_pfdset, set.fdset(), set._nfdSize);
}
~CELLFDSet() {
if (_pfdset)
{
delete[] _pfdset;
_pfdset = nullptr;
}
}
private:
//动态创建大小
fd_set * _pfdset = nullptr;
size_t _nfdSize;
};
#endif