c++ - Winsock2 选择() : multiple events on the same socket is possible?

标签 c++ sockets select winsock2

根据 this page :

The select function returns the total number of socket handles that are ready and contained in the fd_set structures.

如果我只向每个 FD_SET 添加一个(且相同的)SOCKET 并将它们传递给选择?这意味着我必须在同一个套接字上处理多个事件。示例:

SOCKET someRandomSocket;

FD_SET readfds;
FD_SET writefds;
FD_SET exceptfds;

timeval timeout;
/* ...
Connecting someRandomSocket to another peer.
... */

FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);

FD_SET(someRandomSocket, &readfds);
FD_SET(someRandomSocket, &writefds);
FD_SET(someRandomSocket, &exceptfds);

int total = select(0, &readfds, &writefds, &exceptfds, &timeout);

/* total > 1 is possible? */
/* (FD_ISSET(someRandomSocket, &exceptfds) && (FD_ISSET(someRandomSocket, &readfds) || FD_ISSET(someRandomSocket, &writefds)) == true) possible? */

还有一个问题:是否可能发生我必须同时处理同一个套接字上的异常和非异常事件?

最佳答案

Is it thereotically possible that the return value is greater than 1 if I add only one (and the same) SOCKET to each of the FD_SETs and pass them to select? It would mean that I must handle multiple events on the same socket.

无论 select() 是否在返回值中多次计算相同的 SOCKET(这很容易测试),您应该忽略实际数量。 > 0 的返回值只是告诉您任何 fd_set 包含与请求事件匹配的套接字(select() 修改 fd_sets 删除不匹配的套接字)。即使您知道套接字的总数,您仍然必须使用 FD_ISSET() 检查各个套接字,因此返回值 > 0 时的实际数量在实际处理中意义不大。只有 -1(错误)、0(超时)和 > 0(存在事件)才有意义。

是的,一个套接字可以同时启用多个事件。例如,套接字可以同时是可读和可写的。

例如:

FD_SET readfds;
FD_SET writefds;
FD_SET exceptfds;

FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);

FD_SET(someRandomSocket, &readfds);
FD_SET(someRandomSocket, &writefds);
FD_SET(someRandomSocket, &exceptfds);

timeval timeout;
timeout.tv_sec = ...;
timeout.tv_usec = ...;

int total = select(0, &readfds, &writefds, &exceptfds, &timeout);

if (total == -1)
{
    // error in select() itself, handle as needed...
}
else if (total == 0)
{
    // timeout, handle as needed...
}
else
{
    if (FD_ISSET(someRandomSocket, &exceptfds) )
    {
        // socket has inbound OOB data, or non-blocking connect() has failed, or some other socket error, handle as needed...
    }

    if (FD_ISSET(someRandomSocket, &readfds) )
    {
        // socket has inbound data, or has disconnected gracefully, handle as needed...
    }

    if (FD_ISSET(someRandomSocket, &writefds) )
    {
        // socket is writable, or non-blocking connect() has succeeded, handle as needed...
    }
}

Is it possible to occur that I must handle an exception and also a non-exception event on the same socket at the same time?

这取决于异常的性质。并非所有异常都是 fatal error 。

关于c++ - Winsock2 选择() : multiple events on the same socket is possible?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45620645/

相关文章:

c++ - 创建类类型的动态分配数组,其中类不能有默认构造函数

python - 为什么这个扭曲的服务器会与进程错误地交互?

javascript - 如何将数据从 ajax 加载到 Chosen jquery?

mysql - SQL Raw 到 mysql 查询

Html 5 选择列表选项在 chrome 悬停时更改背景颜色

c++ - g++ 可变参数模板。简单示例代码无法编译,提示 'Not a template'

c++ - 优化编译器如何决定何时以及展开多少循环?

用于读取结构的基于 C++ 范围的循环

sockets - 先发送 UDP 消息再发送 TCP 消息有什么好处吗?

html - 使用fmt.Fprintf()发送文本/纯文本