我正在使用I / O完成端口编写一个小型服务器客户端。
我通过AcceptEx在我的完成端口上成功连接了服务器和客户端。 客户端连接后,客户端套接字与完成端口关联,并调用该套接字上的WSARecv重叠调用。
一切正常,直到我关闭客户端测试程序。
GetQueuedCompletionStatus()
返回FALSE
,GetLastError
返回
ERROR_NETNAME_DELETED
,这对我来说很有意义(在我阅读MSDN上的描述之后)。
但我的问题是,我认为对GetQueuedCompletionStatus
的调用会返回一个数据包,指示由于套接字关闭导致的失败,因为WSARecv
将返回适当的返回值。
由于情况并非如此,我不知道哪些客户端的套接字导致错误,并且无法按照我需要的方式行事(释放结构,清理此特定连接等)...
有关如何解决此问题的建议,或提示?
感谢:)
编辑:http://codepad.org/WeYINasO< - 负责的代码......“错误”在while循环的第一个函数开始时发生(对GetCompletionStatus()
的调用只是GetQueuedCompletionStatus的包装器()在其他情况下工作正常)[发布在那里,因为它看起来很糟糕&凌乱在这里]
答案 0 :(得分:4)
以下是调用GetQueuedCompletionStatus
时需要注意的方案:
GetQueuedCompletionStatus
返回TRUE
:已收到成功完成的数据包,已填写所有输出参数。GetQueuedCompletionStatus
返回FALSE
,lpOverlapped == NULL
:没有数据包退出。其他输出参数包含不确定的值。GetQueuedCompletionStatus
返回FALSE
,lpOverlapped != NULL
:该函数已将失败的完成数据包队列化。错误代码可通过GetLastError
。要回答您的问题,当GetQueuedCompletionStatus
返回FALSE
和lpOverlapped != NULL
时,I / O完成失败。这是你需要关注的lpOverlapped
的价值。
答案 1 :(得分:1)
我知道这是一个老问题,但我发现这个页面虽然没有搜索到有关ERROR_NETNAME_DELETED
的详细信息。这是一个在重叠Readfile()
时得到的错误。
经过一些调试后发现问题是由写入套接字的程序引起的,但在使用closesocket()
之前忘记调用ExitProcess()
(由于垃圾收集问题)。调用CloseHandle()
并未阻止此错误,也未在WSACleanup()
之前添加ExitProcess()
。但是,在客户端退出之前添加短暂睡眠确实可以防止错误。也许避免ExitProcess()
也会阻止这个问题。
所以我怀疑你的问题是由程序退出引起而没有正确关闭套接字。
我认为这不会是Unix上的问题,因为套接字只是普通的文件描述符。