我在网络方面的所有经验都是在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;
}
定义为等于零。
为什么代码在这个看似不必要的减法中变得杂乱无章?显然编译器会优化它,但仍然不明白它为什么存在。
答案 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...
}
鉴于bAlertable
为FALSE
(无法调用I / O例程)且dwTimeout
为WSA_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?