IcmpSendEcho2 -异步调用不是异步的

IcmpSendEcho2 - Asynchronous invocation is not asynchronous

本文关键字:异步 调用 IcmpSendEcho2      更新时间:2023-10-16

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

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

这个事件通知系统工作良好,但我不能得到IcmpSendEcho2异步调用。MSDN说

当指定ApcRoutine或Event参数时,将异步调用IcmpSendEcho2函数。

我确实指定了Event参数,但是调用线程仍然被锁定,直到响应到达或Timeout时间过去。我希望该方法立即返回,并且一旦响应到达或超时时间过去,所提供的事件就会获得信号。至少这是我对"异步"的理解。

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

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 echo请求并返回要么立即(如果Event或ApcRoutine是非null),要么返回在指定的超时时间之后。ReplyBuffer包含ICMP回显信息响应,如果有的话。

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

如果没有按预期工作,有三种可能:

  1. 您的eventHandle为NULL,意味着CreateEvent失败并返回NULL句柄。你查过了吗?
  2. 在异步IcmpSendEcho调用(OP在中建议的)之后关闭ICMP文件句柄(IcmpCloseHandle)。
  3. 如果你正在运行一个防火墙应用程序,它可能会钩住API,无意中破坏异步需求。
  4. 你可能发现了一个Windows错误。