0

我一直在阅读IcmpSendEcho2 的 MSDN 文档,它提出的问题多于回答的问题。

我熟悉来自其他 Win32 API 的异步回调,例如ReadFileEx...IO_PENDING失败(并打电话GetCompletionStatus查明是哪一个)。超时是我的责任,我可以调用CancelIo来中止处理,但缓冲区仍然保留,直到驱动程序取消操作并调用我的完成例程,状态为CANCELLED. 并且有一个OVERLAPPED结构可以通过所有这些唯一地标识请求。

IcmpSendEcho2OVERLAPPED为异步请求使用上下文结构。如果 ping 超时或失败(故障可能是缺少网络连接、本地对等方缺少 ARP 条目、来自远程对等方的中间路由器的 ICMP 目标无法到达响应等),文档不清楚。

有谁知道回调是否发生在超时和/或失败时?特别是,如果没有响应,我可以将缓冲区重新用于另一个调用,IcmpSendEcho2还是永久保留以防回复迟到?

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

回调的方式也有一个丑陋的不兼容。看起来第一个参数在两个签名之间是一致的,所以PIO_APC_ROUTINE只要我只在操作系统版本检查返回 Vista 或更新版本时才使用第二个参数,我就应该能够使用更新的参数?尽管 MSDN 说“不要进行 Windows 版本检查”,但似乎我需要这样做,因为带有新参数的版本集与 iphlpapi.dll 中存在该函数的版本集不同。

指向使用此功能和 APC 的其他文档或工作代码的指针将不胜感激。

如果这完全是错误的方法,请告诉我——即,如果使用原始套接字或IcmpCreateFile++的WriteFileEx某种组合ReadFileEx会更健壮。

4

1 回答 1

1

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

至于版本检查,您可以通过使用事件RegisterWaitForSingleObject而不是 APC 回调来避免它。

于 2011-03-14T16:08:09.443 回答