【发布时间】:2011-08-21 19:51:38
【问题描述】:
我需要弄清楚当 lpCompletionRoutine 为空时 WSARecv 如何使用 lpOverlapped 参数。它表示位于 lpOverlapped 中的事件,对吗?但肯定不止于此。
我正在拦截正常的 WSARecv 调用,以便记录数据包,并且可以很好地捕获数据,但是客户端挂起并等待被告知 recv 操作已完成。我只是不知道真正的 WSARecv 函数如何使用 lpOverlapped 来通知客户端操作已完成。
当 lpOverlapped 被传入 WSARecv 时,lpOverlapped->hEvent 为空。所以我不能简单地做 SetEvent() 或 WSASetEvent()。我可以通过执行 lpOverlapped->hEvent = WSACreateEvent() 之类的操作来创建一个事件,然后设置该事件,客户端似乎仍然不承认它。
感谢任何帮助。
谢谢!
编辑:我为 WSARecv 调用所做的示例
int proxyWSARecv(int unused, SOCKET s, LPWSABUF recvBuffer, DWORD bufferCount, LPDWORD bytesRecvd, LPDWORD flags,
LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine){
WSAOVERLAPPED wsaoverlapped;
LPWSAOVERLAPPED ourOverlapped = &wsaoverlapped;
WSADATA wsaData;
int rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
int retnVal;
__asm{
push lpCompletionRoutine
push ourOverlapped // our replacement lpoverlapped
push flags
push bytesRecvd
push bufferCount
push recvBuffer
push s
call p_WSARecv // real WSARecv
mov retnVal, EAX
}
// get overlapped results and log packets here. etc
}
【问题讨论】:
-
客户端可能正在使用I/O completion ports?
-
好吧,除了 lpOverlapped 之外,我正在使用客户端正在使用的所有相同变量。在那种情况下客户不会继续进行吗? (我将更新我的主要帖子以展示我正在做的一个例子)
-
如果客户端正在使用 I/O 完成端口,他们可能正在使用
GetQueuedCompletionStatus,并且可能会根据返回的lpOverlapped值键入自己的处理,而不是仅使用完成键.在这种情况下,覆盖lpOverlapped将导致失败。您可以做的是保存调用者的 lpOverlapped 结构,并用您自己的内容覆盖它以保留地址。 (如果我在这里没有完全偏离标记,我可能会将其发布为答案) -
好的,有没有办法我自己触发 GetQueuedCompletionStatus 的东西?主要的是我需要在游戏解密数据包之前复制整个数据包(以记录它)。如果我使用提供的 lpOverlapped,通常当我看到它时,数据包已经在内存中发生了变化。顺便说一句,我真的很感谢你的 cmets。
-
你为什么从你的代理程序调用 WSAStartup?主机应用程序不应该为您执行此操作,可能需要不同的版本吗?