使用IcmpSendEcho2和异步回调

时间:2011-01-26 17:58:53

标签: winapi asynchronous apc ping icmp

我一直在阅读MSDN documentation for IcmpSendEcho2,它提出的问题多于答案。

我熟悉来自其他Win32 API的异步回调,例如ReadFileEx ...我提供了一个缓冲区,我保证将其保留供驱动程序使用,直到操作完成除{{1}以外的任何结果如果成功或失败,我得到回调(并调用IO_PENDING找出哪个)。超时是我的责任,我可以调用GetCompletionStatus来中止处理,但缓冲区仍然保留,直到驱动程序取消操作并调用状态为CancelIo的完成例程。并且有一个CANCELLED结构,通过所有这些来唯一地标识请求。

OVERLAPPED不对异步请求使用IcmpSendEcho2上下文结构。并且文档不清楚 过分简约关于ping超时或失败会发生什么(失败将缺少网络连接,缺少本地对等的ARP条目,ICMP来自中间路由器的远程对等的目的地不可达响应等。)

有人知道回叫是否发生在超时和/或失败?特别是,如果没有响应,我是否可以重新使用缓冲区进行OVERLAPPED的另一次调用,或者它是否会被永久保留以备迟到的回复?

我想从Win32服务中使用这个函数,这意味着我必须正确处理错误处理案例,我不能只是泄漏缓冲区(或者如果API确实泄漏缓冲区,我必须使用帮助程序,所以我有办法放弃请求。)

回调的方式也存在丑陋的不兼容性。看起来第一个参数在两个签名之间是一致的,所以我应该能够使用更新的IcmpSendEcho2,只要我只使用第二个参数,如果操作系统版本检查返回Vista或更新?虽然MSDN说“不做Windows版本检查”,但似乎我需要,因为带有new参数的版本集与iphlpapi.dll中函数所在的版本集不同。 / p>

非常感谢使用此功能和APC的其他文档或工作代码的指示。

如果这是完全错误的方法,也请告诉我 - 即使用原始套接字或PIO_APC_ROUTINE + IcmpCreateFile + WriteFileEx的某种组合会更加健壮。< / p>

1 个答案:

答案 0 :(得分:1)

我将IcmpSendEcho2用于事件,而不是回调,但我认为两种情况下的流程都相同。 IcmpSendEcho2在内部使用NtDeviceIoControlFile。它会在早期检测到一些与ICMP相关的错误,并将它们作为12xx范围内的错误代码返回。如果(且仅当)IcmpSendEcho2返回ERROR_IO_PENDING,它最终将调用回调和/或设置事件,无论是否成功,失败或超时。您传入的任何缓冲区必须保留到那时,但之后可以重复使用。

对于版本检查,您可以使用RegisterWaitForSingleObject而不是APC回调的事件以较低的成本避免它。