C++ IcmpSendEcho2-异步调用不是异步的

C++ IcmpSendEcho2-异步调用不是异步的,c++,winapi,C++,Winapi,我正在使用发送ICMP回显请求到我要检查的主机。但是,我需要在单独的接收器线程中异步处理响应 为了实现这一点,我为发送的每个请求创建了一个新的Windows事件句柄(CreateEvent)。接收线程将收到通知,并使用WaitForMultipleObjects等待传入的答复 此事件通知系统工作正常,但我无法异步调用IcmpSendEcho2。MSDN说 当指定APCProutine或事件参数时,将异步调用IcmpSendEcho2函数 我确实指定了事件参数,但在响应到达或超时时间过去之前,调用

我正在使用发送ICMP回显请求到我要检查的主机。但是,我需要在单独的接收器线程中异步处理响应

为了实现这一点,我为发送的每个请求创建了一个新的Windows事件句柄(
CreateEvent
)。接收线程将收到通知,并使用
WaitForMultipleObjects
等待传入的答复

此事件通知系统工作正常,但我无法异步调用
IcmpSendEcho2
。MSDN说

当指定APCProutine或事件参数时,将异步调用IcmpSendEcho2函数

我确实指定了事件参数,但在响应到达或超时时间过去之前,调用线程仍然处于锁定状态。我希望该方法立即返回,并在响应到达或超时时间过去后立即通知提供的事件。至少这是我对“异步”的理解

这是我对函数的调用,提供的参数有效:

dwResult = IcmpSendEcho2(
    icmpFileHandle,
    eventHandle,
    NULL, //no apcRoutine   
    NULL, //no apcContext
    ((sockaddr_in*)addrInfo->ai_addr)->sin_addr.S_un.S_addr,
    &requestData,
    sizeof(requestData),
    &requestOptions,
    &icmp4ReplyBuffer,
    sizeof(icmp4ReplyBuffer),
    30000);
MSDN是否对“异步”有不同的理解,或者我有什么做错了吗?

根据:

IcmpSendEcho2函数发送IPv4 ICMP回显请求并返回 立即(如果事件或APCProutine为非NULL)或返回 在指定的超时之后。ReplyBuffer包含ICMP回显 答复,如果有的话

您对异步的理解是正确的,如果您传递了一个非NULL事件,它应该立即返回

如果未按预期工作,则有3种可能性:

  • 您的
    eventHandle
    为空,这意味着
    CreateEvent
    失败并返回空句柄。你查过了吗
  • 您正在关闭ICMP文件句柄(
    IcmpCloseHandle
    ),就在异步
    IcmpSendEcho
    调用(由OP在注释中建议)之后
  • 如果您运行的是防火墙应用程序,它可能会挂接该API,无意中破坏异步要求
  • 你可能发现了一个Windows bug

  • 谢谢你的回复。1.如果我的eventHandle实际上为NULL,我相信WaitForMultipleObjects不会接收事件并在事件句柄数组中返回正确的索引。不过,我只是仔细检查了一下,可以确定我的事件句柄绝对不是空的。2.你所说的“防火墙应用程序”到底是什么意思?如果这意味着Windows防火墙会干扰,我尝试禁用它并以提升的权限运行应用程序,但没有帮助。3.我相信在我之前会有人注意到。那么,我应该在微软的某个官方论坛上报告这个问题。1)很好。2) 好的,这不太可能,但我在过去见过使用API挂钩的防火墙。3) 可能是的。您是否准备并发布一个最小的工作(编译)代码,以便我们可以重现问题?您使用的是哪个Windows版本?可能添加选项4:不要在异步IcmpSendEcho调用后直接关闭Icmp文件句柄(IcmpCloseHandle)。在创建一个最小的示例时,我没有重现这一点,并注意到我只是这样做了,显然在这种情况下,IcmpCloseHandle将锁定,直到发生事件(超时或回复)。所以,这肯定是我的错误,但出乎意料。最奇怪的问题总是有最简单的原因。。。谢谢你的帮助!哦,有道理。干得好!:)根据您的建议更新了答案。