Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi 通过异步回调使用IcmpSendEcho2_Winapi_Asynchronous_Apc_Ping_Icmp - Fatal编程技术网

Winapi 通过异步回调使用IcmpSendEcho2

Winapi 通过异步回调使用IcmpSendEcho2,winapi,asynchronous,apc,ping,icmp,Winapi,Asynchronous,Apc,Ping,Icmp,我一直在读这本书,它提出的问题多于它的答案 我熟悉来自其他Win32 API的异步回调,例如ReadFileEx。。。我提供一个缓冲区,我保证将保留该缓冲区供驱动程序使用,直到操作完成并产生除IO_PENDING以外的任何结果,如果成功或失败,我将收到回调(并调用GetCompletionStatus以确定是哪个)。超时是我的责任,我可以调用CancelIo中止处理,但缓冲区仍然保留,直到驱动程序取消操作并调用状态为CANCELLED的完成例程。还有一个重叠的结构,它通过所有这些唯一地标识请求

我一直在读这本书,它提出的问题多于它的答案

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

IcmpSendEcho2
不为异步请求使用
OVERLAPPED
上下文结构。文件中也不清楚如果ping超时或失败会发生什么(失败的原因是缺少网络连接、本地对等方缺少ARP条目、远程对等方无法从干预路由器获得ICMP目的地响应等)

有人知道回调是否发生在超时和/或失败时吗?特别是,如果没有响应,我是否可以将缓冲区重新用于对
IcmpSendEcho2
的另一个调用,或者它是否永远保留以防响应延迟

我想从Win32服务中使用这个函数,这意味着我必须正确处理错误案例,我不能仅仅泄漏缓冲区(或者如果API确实泄漏缓冲区,我必须使用帮助进程,这样我就可以放弃请求)

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

对于使用此函数和APC的其他文档或工作代码的指针,我们将不胜感激


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

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


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

我使用IcmpSendEcho2Ex的经验是,使用事件、回调函数和超时调用记录在案的Vista样式回调,但是唯一有效的参数是第一个,用于XP风格的回调。如果事件尚未触发,则我还保留内存,直到超时过期。似乎没有任何安全的方法来取消请求。详情如下: