代码之家  ›  专栏  ›  技术社区  ›  poby

重叠IO中wsa_wait_0事件的目的是什么?

  •  0
  • poby  · 技术社区  · 5 年前

    我在网络方面的所有经验都是在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_事件 定义于 winsock2.h 等于零。

    为什么代码中充斥着这种看似不必要的减法?很明显,编译器会优化它,但仍然不明白它为什么会存在。

    2 回复  |  直到 5 年前
        1
  •  1
  •   Remy Lebeau    5 年前

    事实上 WSA_WAIT_EVENT_0 定义为0是 无关的 (它只是 WAIT_OBJECT_0 WaitFor(Single|Multiple)Object(s)() API,也定义为0- WSAWaitForMultipleEvents() 它本身就是 WaitForMultipleObjectsEx() 不过,微软保留在不破坏现有用户代码的情况下更改实现的权利)。

    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 (无法超时),因此只有两种可能的结果-事件已发出信号或发生错误:

    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...
    }
    
        2
  •  0
  •   user253751    5 年前

    The documentation 说它会回来的 WSA_WAIT_EVENT_0 如果事件0已发出信号, WSA_WAIT_EVENT_0 + 1 如果事件1已发出信号,依此类推。

    当然,他们定了 wsa_wait_事件 0 在这个版本的windows中,如果下一个版本是1,或者100呢?

    推荐文章