gpt4 book ai didi

c++ - closesocket() 未完成 IOCP 的挂起操作

转载 作者:行者123 更新时间:2023-12-03 12:49:09 33 4
gpt4 key购买 nike

我目前正在使用 C++ 开发服务器应用程序。我的主要灵感来自这些例子:

Windows SDK IOCP Excample

The I/O Completion Port IPv4/IPv6 Server Program Example

我的应用程序与这些应用程序非常相似(socketobj、packageobj...)。

总的来说,我的应用程序运行没有问题。唯一仍然给我带来麻烦的是半开放的连接。

我的策略是:我检查一段时间内每个连接的客户端并计算“空闲计数器”。如果发生一次完成,我会重置该计时器。如果空闲计数器太高,我会设置一个 bool 值以防止其他线程发布操作,然后调用 closesocket()

我的假设是,现在套接字已关闭,挂起的操作将完成(可能不是立即完成,而是在一段时间后完成)。这也是 MSDN 文档描述的行为(提示,第二段)。我需要这个,因为只有在所有操作完成后我才能释放资源。

长话短说:我的情况并非如此。我使用 testclient 应用程序进行了一些测试,并进行了一些 cout 和断点调试,发现关闭套接字的挂起操作未完成(即使等待 10 分钟后)。我也已经尝试在 closesocket() 之前调用 shutdown(),并且都没有返回错误。

我做错了什么?其他人也有遇到同样的状况吗? MSDN文档有错吗?有哪些替代方案?

我目前正在考虑“linger”功能,或者使用 CancelIoEx() 函数显式取消每个操作

编辑:(感谢您的回复)

昨天晚上,我为每个 sockedobj 添加了一个链表,以保存待处理操作的每个 io obj。我尝试了 CancelIOEx() 函数。对于大多数操作,该函数返回 0,GetLastError() 返回 ERROR_NOT_FOUND

在这种情况下,仅释放每个 Io Obj 是否安全?

我还发现,当我在同一台计算机上运行服务器应用程序和客户端应用程序时,这种情况发生得更频繁。有时会发生服务器无法完成写入操作的情况。我认为发生这种情况是因为客户端接收缓冲区已满。 (客户端并没有停止接收数据!)。

我们将尽快截取代码。

最佳答案

  • “linger”设置可用于重置连接,但这样您将 (a) 丢失数据并 (b) 向对等方发送重置消息,这可能会吓到它。
  • 如果您正在考虑积极的逗留超时,那并没有多大帮助。
  • 关闭读取应该终止读取操作,但关闭写入只会在挂起的写入之后排队,因此根本没有帮助。
  • 如果待处理的写入是问题所在,并且未完成,则必须取消这些写入。

关于c++ - closesocket() 未完成 IOCP 的挂起操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46703070/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com