我一直试图在 UDP 数据包到达应用程序逻辑之前拦截它们。更准确地说,该应用程序正在使用 DirectPlay 服务器并且没有源。所以我发现 DirectPlay 通过发布多个 WSARecvFrom 使用异步 IO,然后让一些工作线程等待 WaitForSingleObject,最后使用 WSAGetOverlappedResult 检索 IO 状态。
当 WSARecvFrom 返回时,当然 lpBuffers 还没有填充数据,因为操作仍然处于挂起状态,稍后会完成。
所以我获取数据的想法是为每个 WSARecvFrom 调用将 lpOverlapped/lpBuffers 对保存在 std::map 中,然后,如果 IO 操作完成(在 WSAGetOverlappedResult 中),我将得到相应的(现在已填充)lpBuffers通过查找地图中的 lpOverlapped。
但是,似乎存在一个大问题:DirectPlay 有时会使用相同的 lpOverlapped 地址多次调用 WSARecvFrom,即使使用相同的 lpOverlapped->hEvent 或 lpBuffers 地址,也是针对同一个套接字(此时这些操作均未完成,所以他们都在等待中)。我不明白为什么会发生这种情况,文档清楚地说:“如果多个 I/O 操作同时未完成,则每个操作都必须引用一个单独的 WSAOVERLAPPED 结构。” 因此,我无法正确检索 lpBuffers,因为当调用 WSAGetOverlappedResult 时,我不知道 lpOverlapped 对应于哪个 WSARecvFrom,因为调用了多个 WSARecvFrom,每个都具有相同的 lpOverlapped!怎么会这样?有谁知道 DirectPlay 是如何处理这个问题的?是否有另一种拦截(并最终丢弃)UDP数据包的方法?(我不想使用驱动程序)
(我尝试这样做有一个很好的理由:有人正在使用 DirectPlay 向游戏服务器发送被利用的 UDP 数据包,它“混淆”了 DirectPlay 逻辑,基本上关闭了服务器。所以我必须过滤掉特定的 UDP数据包甚至在到达 DirectPlay 之前)
很高兴任何提示!
非常感谢!