如何处理钩住的WSARecv

时间:2013-09-01 13:04:43

标签: c sockets winapi hook

我正在开展涉及挂钩WSARecv的项目。我知道如何挂钩这个函数,我的意思是它与挂钩另一个函数一样。无论如何,困难的部分是当WSARecv用于执行重叠操作时。这个想法是,当一个应用程序接收数据来拦截它并且可以修改它时,我正在使用管道。本机DLL将所有数据隧道传送到托管“服务器”。这将处理输入等并将其返回到本机DLL。这适用于WSASendsendrecv。然而,困难的部分是当应用程序使用重叠套接字时。

所以我需要先收到的数据才能处理,这是很难的部分。我该怎么办?我想到了这一点,但它们看起来都像是一团糟:

使用WSAOverlapped调用WSARecv时: 创建一个新线程,使用WaitForSingleObject并传递WSAOverlapped结构的hEvent。当事件发出信号时,将数据处理到受管服务器并将数据传递给程序。

使用完成例程调用WSARecv时: 创建一个新线程,使用lpOperationCompleted将对原始函数的调用修改为新函数。使用SleepEx将线程置于可警告状态。当调用OperationCompleted处理数据并将数据传递回程序时。

我可以发布我的代码,但我没有写,因为它似乎是一个糟糕的解决方案..所以没有真正的重点。

我无法想到更好的解决方案,这看起来很糟糕,因为当应用程序调用{​​{1}}很多时(例如使用重叠套接字处理大量客户端的大型服务器),它会为每个调用创建一个新线程,这似乎是一个坏主意。

那我该怎么做呢?

1 个答案:

答案 0 :(得分:4)

无需为每个重叠的IO调用创建一个线程。

当使用重叠操作时,它们要么具有关联事件(您可以放心地忽略),完成例程,要么与I / O完成端口关联。

要处理前两种情况,您应该同时挂钩WSARecv()WSAGetOverlappedResult()

如果你需要处理最后一个,你还需要挂钩GetQueuedCompletionStatus()

现在,当你接到WSARecv()的调用时,对于事件情况,你没有做任何特别的事情(除了可能保存一些与lpOverlapped有关的信息,例如缓冲区),以及处理WSAGetOverlappedResult()中的数据(应用程序必须调用该数据才能获得成功/错误和传输的字节。)

如果存在完成例程,请保存lpOverlappedlpCompletionRoutine,并将您自己的完成例程传递给真实的WSARecv()

您的例程应处理数据并调用原始完成例程。

要处理I / O完成端口的情况,请在WSARecv()lpOverlapped保存GetQueuedCompletionStatus()和缓冲区等,调用原始文件,如果返回的重叠结构匹配,则处理数据。

您还应注意,重叠操作可能会立即完成,在这种情况下,不会发出事件信号,不会调用完成例程,并且(IIRC)IOCP上没有完成排队。