问题描述
我正在研究winsock2中的select api。 fdread是fd_sets,包含所有能够读取的套接字。我发现在大多数arcticles中,readfds不是直接遍历的。而是通过FD_ISSET(FD_ISSET(fdSocket.fd_array [i],&fdread))遍历和判断fdSocket。我已经尝试了两种方法,并且都可行。所以我的问题是:为什么不直接遍历readfds?
fd_set fdSocket;
FD_ZERO(&fdSocket);
FD_SET(sock_listen,&fdSocket);//add sock_listen to fdSocket
while (true)
{
fd_set fdread = fdSocket;
if (select(NULL,&fdread,NULL,NULL) <= 0) break;
for (int i = 0; i < (int)fdSocket.fd_count; ++i)
{
if (FD_ISSET(fdSocket.fd_array[i],&fdread))
{
if (fdSocket.fd_array[i] == sock_listen)
{
//do something
}
else
{
//do something
}
}
}
}
fd_set fdSocket;
FD_ZERO(&fdSocket);
FD_SET(sock_listen,NULL) < 0) break;
for (int i = 0; i < (int)fdread.fd_count; ++i)
{
if (fdread.fd_array[i] == sock_listen)
{
//do something
}
else
{
//do something
}
}
}
解决方法
这是一种可移植性措施,也是尝试编写代码的尝试
看起来类似于POSIX规范。 fd_set
的实现方式有所不同
直接访问fd_set
结构的内容不能跨平台移植(也不能直接复制fd_set
结构)。 fd_set
在Windows上使用纯C样式数组的事实只是一个实现细节。
如果您需要编写可移植套接字代码,则使用FD_ISSET()
,FD_COPY()
和其他相关宏是可移植解决方案。否则,完全不要使用select()
,而应使用(e)poll()
(在Windows上是WSAPoll()
),这样您就可以管理自己的套接字数组,该套接字仅在状态信息更新时才更新叫。