我目前正在C++中开发一个服务器应用程序。我的主要灵感来自以下例子:
I/O完成端口IPv6 4/IPv6 6服务器程序实例
我的应用程序非常类似于这些程序(socketobj,packageobj,.)。
总的来说,我的应用程序运行时没有问题。唯一给我带来麻烦的是半开放的联系。
我的策略是:在一段时间内检查每个连接的客户端,并计算一个“空闲计数器”。如果出现一个完成,我会重置这个计时器。如果空闲计数器太高,则设置一个布尔值以防止其他线程提交操作,然后调用closesocket()。
我的假设是,现在套接字已经关闭,挂起的操作将完成(可能不是立即,而是过了一段时间)。这也是MSDN文档描述的行为(提示,第二段)。我需要这样做,因为只有在所有操作完成之后,我才能释放资源。
长话短说:对我来说不是这样。我用testclient应用程序和cout和断点调试做了一些测试,发现关闭套接字的挂起操作还没有完成(即使在等待10分钟之后)。我还在shutdown()之前尝试过使用closesocket()调用,两者都没有返回错误。
我做错了什么?这发生在其他人身上吗?MSDN文档错误吗?有什么可供选择的?
我目前正在考虑“逗留”功能,或者使用CancelIoEx()函数显式取消每个操作。
编辑:(感谢您的回复)
昨天晚上,我为每个sockedobj添加了一个链表,以保存挂起的操作的per obj。有了这个,我尝试了CancelIOEx()函数。函数返回0,GetLastError()返回大多数操作的GetLastError()。
那么,在这种情况下,仅仅释放是安全的吗?
我还发现,当我在同一台机器上运行服务器应用程序和客户端应用程序时,这种情况会发生得更频繁。服务器有时无法完成写操作,这种情况时有发生。我认为发生这种情况是因为客户端接收缓冲区已满。(客户端不会停止接收数据!)。
下面是代码片段,请尽快执行。
发布于 2017-10-12 07:00:09
https://stackoverflow.com/questions/46703070
复制相似问题