在winsock2中使用select时,直接遍历“ readfdsfdsets”是否合适?

问题描述

我正在研究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()),这样您就可以管理自己的套接字数组,该套接字仅在状态信息更新时才更新叫。