首页 > 解决方案 > 重叠 IO 中 WSA_WAIT_EVENT_0 的用途是什么?

问题描述

我在网络方面的所有经验都在 Linux 上,所以我是 Windows 网络的绝对初学者。这可能是一个愚蠢的问题,但我似乎无法在任何地方找到答案。考虑以下代码片段:

    DWORD Index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);
    WSAResetEvent( EventArray[Index - WSA_WAIT_EVENT_0]);

每次从 EventArray 中选择事件时,都会WSA_WAIT_EVENT_0从索引中减去,但WSA_WAIT_EVENT_0定义winsock2.h为等于 0。

为什么代码会被这种看似不必要的减法弄得乱七八糟?显然编译器会优化它,但仍然不明白它为什么在那里。

标签: cwinsock2overlapped-io

解决方案


WSA_WAIT_EVENT_0定义为 0的事实无关紧要(它只是 API 的别名WAIT_OBJECT_0WaitFor(Single|Multiple)Object(s)()也定义为 0 -WSAWaitForMultipleEvents()本身只是 的包装器WaitForMultipleObjectsEx(),尽管 Microsoft 保留在不破坏现有用户的情况下在未来更改实现的权利代码)。

WSAWaitForMultipleEvents()一次可以对多个事件进行操作,其返回值将是以下几种可能之一:

WSA_WAIT_EVENT_0 .. (WSA_WAIT_EVENT_0 + cEvents - 1)

已发出特定事件对象的信号。

WSA_WAIT_IO_COMPLETION

执行了一个或多个警报 I/O 完成例程。

WSA_WAIT_TIMEOUT

发生超时。

WSA_WAIT_FAILED

功能失败。

通常,代码应该查看返回值并采取相应的行动,例如:

DWORD ReturnValue = WSAWaitForMultipleEvents(...);
if ((ReturnValue >= WSA_WAIT_EVENT_0) && (ReturnValue < (WSA_WAIT_EVENT_0 + EventTotal))
{
    DWORD Index = ReturnValue - WSA_WAIT_EVENT_0;
    // handle event at Index as needed...
}
else if (ReturnValue == WSA_WAIT_IO_COMPLETION)
{
    // handle I/O as needed...
}
else if (RetunValue == WSA_WAIT_TIMEOUT)
{
    // handle timeout as needed...
}
else
{
    // handle error as needed...
}

bAlertable考虑到is FALSE(不能调用 I/O 例程)和dwTimeoutis (不能超时),这可以简化WSA_INFINITE,因此只有两种可能的结果 - 发出事件信号或发生错误:

DWORD ReturnValue = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);
if (ReturnValue != WSA_WAIT_FAILED)
{
    DWORD Index = ReturnValue - WSA_WAIT_EVENT_0;
    WSAResetEvent(EventArray[Index]);
}
else
{
    // handle error as needed...
}

推荐阅读