WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?
Posted
技术标签:
【中文标题】WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?【英文标题】:How does WSARecv make use of lpOverlapped? How can I manually signal the event? 【发布时间】: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?主机应用程序不应该为您执行此操作,可能需要不同的版本吗?
【参考方案1】:
在设置重叠结构时,您必须手动创建(然后关闭)事件。该事件由操作系统设置 - 您只需等待或检查它。
如果重叠结构的事件为NULL,仍然可以通过socket本身来等待socket事件。
【讨论】:
啊,我明白了。谢谢。那么客户端可能会挂起,因为它只是监视套接字事件本身?嗯等等,这不可能。我可以创建自己的 lpOverlapped 并很好地使用它,问题是使用我的 WSARecv 调用的客户端不知道 recv 何时完成。另外,不应该已经设置 lpOverlapped ,因为客户端将它传递给 WSARecv (我正在尝试在视频游戏中记录数据包)以上是关于WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?的主要内容,如果未能解决你的问题,请参考以下文章
如何知道完成数据包是针对 WSASend() 还是 WSARecv() 还是 AcceptEx()?
我可以在 IOCP WSARecv 函数中使用 std::string 吗?