我一直在阅读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>
答案 0 :(得分:1)
我将IcmpSendEcho2
用于事件,而不是回调,但我认为两种情况下的流程都相同。 IcmpSendEcho2
在内部使用NtDeviceIoControlFile
。它会在早期检测到一些与ICMP相关的错误,并将它们作为12xx范围内的错误代码返回。如果(且仅当)IcmpSendEcho2
返回ERROR_IO_PENDING
,它最终将调用回调和/或设置事件,无论是否成功,失败或超时。您传入的任何缓冲区必须保留到那时,但之后可以重复使用。
对于版本检查,您可以使用RegisterWaitForSingleObject
而不是APC回调的事件以较低的成本避免它。