WSA_WAIT_EVENT_0 在重叠 IO 中的目的是什么?

What is the purpose of WSA_WAIT_EVENT_0 in overlapped IO?

我在网络方面的所有经验都来自 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_0winsock2.h 中定义为等于零。

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

The documentation 表示如果事件 0 发出信号,它将 return WSA_WAIT_EVENT_0,如果事件 1 发出信号,WSA_WAIT_EVENT_0 + 1,依此类推。

当然,他们在 Windows 的这个版本中将 WSA_WAIT_EVENT_0 设置为 0,但是如果在下一个版本中设置为 1,或者 100 怎么办?

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

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

WSA_WAIT_EVENT_0 .. (WSA_WAIT_EVENT_0 + cEvents - 1)

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

WSA_WAIT_IO_COMPLETION

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

WSA_WAIT_TIMEOUT

发生超时。

WSA_WAIT_FAILED

函数失败。

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

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...
}

考虑到 bAlertableFALSE(不能调用 I/O 例程)并且 dwTimeoutWSA_INFINITE(不能超时可以过去),因此只有 2 种可能的结果 - 发出事件信号或发生错误:

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...
}