WSA_WAIT_EVENT_0在重叠IO中的用途是什么?

时间:2018-06-18 02:52:41

标签: c winsock2 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_0,但winsock2.h中的@Transient public CommonsMultipartFile getFile() { return file; } 定义为等于零。

为什么代码在这个看似不必要的减法中变得杂乱无章?显然编译器会优化它,但仍然不明白它为什么存在。

2 个答案:

答案 0 :(得分:1)

WSA_WAIT_EVENT_0被定义为0的事实无关(它只是来自WAIT_OBJECT_0 API的WaitFor(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...
}

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

答案 1 :(得分:0)

The documentation表示如果事件0已发出信号,则会返回WSA_WAIT_EVENT_0,如果事件1已发出信号,则会返回WSA_WAIT_EVENT_0 + 1,依此类推。

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