# loop_in_codes

## 突破select的FD_SETSIZE限制

Author : Kevin Lynx

C语言的偏方：

typedef struct _str_type
{

int _len;

char _s[1];
}
str_type;

str_type用于保存字符串(我只是举例，事实上这个结构体没什么用处)，乍看上去str_type只能保存长度为
1的字符串('\0')。但是，通过写下如下的代码，你将突破这个限制：

int str_len = 5;
str_type
*s = (str_type*) malloc( sizeof( str_type ) + str_len - 1 );
//
free( s );

winsock2.h :

typedef
struct fd_set {
u_int fd_count;
/* how many are SET? */
SOCKET  fd_array[FD_SETSIZE];
/* an array of SOCKETs */
}
fd_set;

winsock2.h :

#define FD_SET(fd, set) do { \
u_int __i; \

for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \

if (((fd_set FAR *)(set))->fd_array[__i] == (fd)) { \

break; \
}
\
}
\

if (__i == ((fd_set FAR *)(set))->fd_count) { \

if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) { \
((fd_set FAR
*)(set))->fd_array[__i] = (fd); \
((fd_set FAR
*)(set))->fd_count++; \
}
\
}
\
}
while(0)

FD_SET会将fd_count与FD_SETSIZE相比较，这里主要是防止往fd_array的非法位置写数据。

#define MY_FD_SET( fd, set, size ) do { \
unsigned
int i = 0; \

for( i = 0; i < ((fd_set*) set)->fd_count; ++ i ) { \

if( ((fd_set*)set)->fd_array[i] == (fd) ) { \

break; \
}
\
}
\

if( i == ((fd_set*)set)->fd_count ) { \

if( ((fd_set*)set)->fd_count < (size) ) { \
((fd_set
*)set)->fd_array[i] = (fd); \
((fd_set
*)set)->fd_count ++; \
}
\
}
\
}
while( 0 )

unsigned int count = 100;
fd_set
*read_set = (fd_set*) malloc( sizeof( fd_set ) + sizeof(SOCKET) * (count - FD_SETSIZE ) );
SOCKET s
= socket( AF_INET, SOCK_STREAM, 0 );
//
//
closesocket( s );

int r = select( 0, &read_set, 0, 0, &timeout );
if( r < 0 )
{

// select error
}

if( r > 0 )
{

for( each sockets )

{

if( FD_ISSET( now_socket, &read_set ) )

{

// this socket can read data
}

}

}

int r = select( 0, read_set, write_set, 0, &timeout );
//  error handling
for( int i = 0; i < read_set->fd_count; ++ i )
{

}

for( int i = 0; i < write_set->fd_count; ++ i )
{

// 轮询所有socket，检查其whether can write，判断方式同上
}

posted on 2008-05-20 11:20 Kevin Lynx 阅读(22134) 评论(12)  编辑 收藏 引用 所属分类: game developnetwork

### 评论

@2nd guest

@eXile

#### #re: 突破select的FD_SETSIZE限制 2008-05-20 16:44 hsen

__WSAFDIsSet 好像是Windows的API吧。Windows下的select有这个限制吗？  回复  更多评论

@christanxw

#### #re: 突破select的FD_SETSIZE限制[未登录] 2010-05-14 23:58 ttylikl

do{}while(0)的解释错误呢

if(****)
FD_SET(....);
else
FD_SET(....);

#### #re: 突破select的FD_SETSIZE限制 2011-01-21 11:10 jmzz

ws2_32.dll中_WSAFDIsSet的实现

int __stdcall _WSAFDIsSet(SOCKET fd, fd_set *a2)
{
int result; // eax@1
u_int v3; // ecx@1
char *v4; // edx@2

v3 = a2->fd_count;
result = 0;
if ( a2->fd_count )
{
v4 = (char *)&a2->fd_array[v3];
do
{
v4 -= 4;
if ( *(_DWORD *)v4 == fd )
result = 1;
--v3;
}
while ( v3 );
}
return result;
}
回复  更多评论

#### #re: 突破select的FD_SETSIZE限制 2013-08-31 15:30 lkz

MSDN说了，在include头文件前重新定义FD_SETSIZE即可……  回复  更多评论

 只有注册用户登录后才能发表评论。 相关文章: