简体   繁体   English

在winsock2中使用select时直接遍历readfds(fdsets)是否合适?

[英]Is it appropriate to traverse “readfds(fdsets)” directly when using select in winsock2?

I am studying select api in winsock2.我正在学习 winsock2 中的 select api。 fdRead is the fd_sets contains all the sockets that are able to read. fdRead 是 fd_sets 包含所有能够读取的套接字。 I found in most arcticles readfds is not traversed directly.我发现在大多数文章中 readfds 不是直接遍历的。 Instead, fdSocket is traversed and judged by FD_ISSET(FD_ISSET(fdSocket.fd_array[i], &fdRead)).而是通过 FD_ISSET(FD_ISSET(fdSocket.fd_array[i], &fdRead)) 遍历和判断 fdSocket。 I have tried both two methods and both works.这两种方法我都试过,都有效。 So my question is: why not traversing readfds directly?所以我的问题是:为什么不直接遍历 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, 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, &fdSocket);//add sock_listen to fdSocket
while (true)
{
    fd_set fdRead = fdSocket;
    if (select(NULL, &fdRead, NULL, NULL, 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
        }
    }
}

It's a portability measure and an attempt to make code look similar to POSIX spec.这是一种可移植性措施,并试图使代码看起来类似于 POSIX 规范。 fd_set allowed to vary in implementation fd_set允许在实现中变化

Directly accessing the contents of an fd_set struct is not portable across platforms (neither is directly copying fd_set structs, either).直接访问fd_set结构的内容不能跨平台移植(也不能直接复制fd_set结构)。 The fact that fd_set uses a plain C-style array on Windows is just an implementation detail . fd_set在 Windows 上使用普通 C 样式数组的事实只是一个实现细节

If you need to write portable socket code, using FD_ISSET() , FD_COPY() and other related macros is the portable solution.如果您需要编写可移植的套接字代码,使用FD_ISSET()FD_COPY()等相关宏是可移植的解决方案。 Otherwise, don't use select() at all, use (e)poll() ( WSAPoll() on Windows) instead, which allows you to manage your own array of sockets that the function simply updates with status info when called.否则,根本不要使用select() ,而是使用(e)poll() (Windows 上的WSAPoll() ),它允许您管理自己的套接字数组,该函数在调用时只需更新状态信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM