【发布时间】:2014-08-15 08:43:08
【问题描述】:
注意:OP 在评论线程中确认问题是由于拼写错误,未在发布的代码中显示。
我希望在使用 DisconnectEx 安排重叠断开连接后使用 GetQueuedCompletionStatus 收到通知。我从来没有得到过——这是设计使然吗?如果我在 OVERLAPPED 结构中指定手动重置事件,则会发出信号指示断开连接已完成,但 GetQueuedCompletionStatus 永远不会返回。
我对 DisconnectEx 的调用看起来有点像这样(注意上下文有一个运算符 LPOVERLAPPED 并且 ol 是结构中的第一个元素):
context.ol.hEvent = hEvent;
BOOL result = DisconnectEx(context.socket, context, TF_REUSE_SOCKET, 0);
if (result)
{
// we completed synchronously:
ProcessCompletion(0, context, 0);
}
else
{
int error = WSAGetLastError();
if (error != ERROR_IO_PENDING)
{
throw ServerSocketException("DisconnectEx failed");
}
WaitForSingleObject(hEvent, INFINITE);
std::cout << "disconnected - event signalled\n";
}
当我发现 GetQueuedCompletionStatus 没有返回时,我添加了 WaitForSingleObject。检测 DisconnectEx 完成的正确方法是什么?我想在对 AcceptEx 的调用中再次使用套接字。
【问题讨论】:
-
所以,如果您使用 WaitForSingleObject ,它会按预期工作,但如果您使用 GetQueuedCompletionStatus 它不会?这很奇怪——我很确定 GetQueuedCompletionStatus 在内部调用了 WaitForSingleObject。你能展示一下不工作的代码版本和正常工作的代码版本吗?
-
@HarryJohnston:是的,你是对的。它在调用 WaitForSingleObject 而不是 GetQueuedCompletionStatus 时有效。但是,我认为 GetQueuedCompletionStatus 不会在内部调用 WaitForSingleObject,否则如果您想在超过 64 个套接字上等待就会遇到麻烦(如果您正在开发大容量服务器,您肯定会这样做)。
-
@AdrianS - 这是一个队列 - 你只需要等待一个信号量,无论有多少 IO 完成数据包从内核线程池排队进入它。
-
@LenHolgate 感谢您的评论。我沮丧地添加了等待事件,只是为了看看它是否会发出信号——我从来没有打算使用事件。最后我发现由于一个拼写错误,socket 没有正确关联到端口。
-
您应该添加一个答案,说明这是由于拼写错误,并将该答案设置为已接受,这样人们就不必阅读整个 cmets 线程即可获得结果。跨度>
标签: sockets winsock winsock2 io-completion-ports