IOCP WSASend事件未决

awjx 2009-12-09 12:53:05
最近发现我的服务器的内存在上涨,经过多次走查代码,终于发现问是所在,我简单描述一下我的应用,望大家帮我解决:
为了提高效率,我为每个连接都保持了1~3个WSASend请求,如果WSASend过快的话,前一个WSASend中事件未决,马上又投递了另一个,这样维持在2个左右。现在有一个问是,就是我监测这些IO投递过程中,发现存在大量未决事件,即使在某处调用了closesocket,那些未决事件仍然未返回,而这些未决事就引起了内存泄漏。

我查了大量资料,都是说close后,该连接的所有IO请求都乖乖地返回,可是我却总是没发现有返回呢?
(注,我是通过ByteTransferred == 0来判断是否返回的,正确吗?)

困惑了很久,指望你们了!


...全文
438 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
VirtualDriver 2010-04-23
  • 打赏
  • 举报
回复
似乎这个问题还没有人给出满意的答复

到底是存在楼主的情况

还是楼主的错误代码导致的?
VirtualDriver 2010-04-23
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20091209/13/0594ef65-5ae2-4c4e-a30d-2565f6f49387.html

shenyi0106

(紫色清风)

等 级:
#10楼 得分:100回复于:2009-12-09 16:02:42如需要阅读该回复,请登录或注册CSDN!


======================================
为什么我看不见?
WinEggDrop 2009-12-10
  • 打赏
  • 举报
回复
[Quote=引用楼主 awjx 的回复:]
最近发现我的服务器的内存在上涨,经过多次走查代码,终于发现问是所在,我简单描述一下我的应用,望大家帮我解决:
为了提高效率,我为每个连接都保持了1~3个WSASend请求,如果WSASend过快的话,前一个WSASend中事件未决,马上又投递了另一个,这样维持在2个左右。现在有一个问是,就是我监测这些IO投递过程中,发现存在大量未决事件,即使在某处调用了closesocket,那些未决事件仍然未返回,而这些未决事就引起了内存泄漏。

我查了大量资料,都是说close后,该连接的所有IO请求都乖乖地返回,可是我却总是没发现有返回呢?
(注,我是通过ByteTransferred == 0来判断是否返回的,正确吗?)

困惑了很久,指望你们了!




[/Quote]

如果你一定要投递超过一个以上的WSASend(),弄个计数,WSASend()投递后就加1,WSASend()发送完所有数据就减1.程序退出时就检查每个socket的计数都是为0,如果大于0,那肯定还有没完成的。
awjx 2009-12-09
  • 打赏
  • 举报
回复
补充:原文说维持在2个左右,也许会有人怀疑是因为不断在send,所以存在大量未决事件。
我在观察到这个现象后,我使程序不再投递WSASend,也就是说,如果某个连接存在2个未决事件后不再往这个连接WSASend,很长时间或永远,或close该连接后,那2个未决事件一直都没有返回。

myy 2009-12-09
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 awjx 的回复:]
引用 13 楼 myy 的回复:
要注意在还存在未决操作时,“完成端口句柄”绝对不能关闭,否则肯定都丢掉。


你说的完成端口句柄是指关联的socket吗?
CreateIoCompletionPort((HANDLE)hSocket,
CompletionPort,
(DWORD)pPerHandleData,
0);

就是因为有未决操作,所以我要close啊,如果有未决就不能close,那不是死循环了?

[/Quote]

不是 “关联的socket”是 你的“CompletionPort”
yinshisike 2009-12-09
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 awjx 的回复:]
引用 13 楼 myy 的回复:
要注意在还存在未决操作时,“完成端口句柄”绝对不能关闭,否则肯定都丢掉。


你说的完成端口句柄是指关联的socket吗?
CreateIoCompletionPort((HANDLE)hSocket,
CompletionPort,
(DWORD)pPerHandleData,
0);

就是因为有未决操作,所以我要close啊,如果有未决就不能close,那不是死循环了?

[/Quote]

处理异步事,通常做法是,发送通知,然后等待返回.
如果投递了N多事件,这时要退出,那么只要关闭所有句柄,那么所有未决事件都会返回(也就是GET到).这样走正常出错处理就可以了.
这之后你就要想法等待所有未决事件都处理完后,退出IO线程(也就GET的那个线程,用POST就行).
再之后就是句柄回收的工作,什么完成端口,线程句柄,内存对象,事件对象,等等一切...
yinshisike 2009-12-09
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 awjx 的回复:]
引用 4 楼 yinshisike 的回复:
引用 1 楼 awjx 的回复:
补充:原文说维持在2个左右,也许会有人怀疑是因为不断在send,所以存在大量未决事件。
我在观察到这个现象后,我使程序不再投递WSASend,也就是说,如果某个连接存在2个未决事件后不再往这个连接WSASend,很长时间或永远,或close该连接后,那2个未决事件一直都没有返回。


返回了,只不过完成状态是"错误".


也就是说,close后,并不能通过ByteTransferred == 0来判断返回,而是GET失败表示close的返回吗?

[/Quote]

对头,但不是所有GET都表示CLOSE,如果GET到一个错误值,你需要再投递一次相应的操作,如果此时出错那么就表示真的出错了.或是取一下WSAGetlsatError()值来判断否真的出错.然后再去处理相应的动作.
awjx 2009-12-09
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 myy 的回复:]
要注意在还存在未决操作时,“完成端口句柄”绝对不能关闭,否则肯定都丢掉。
[/Quote]

你说的完成端口句柄是指关联的socket吗?
CreateIoCompletionPort((HANDLE)hSocket,
CompletionPort,
(DWORD)pPerHandleData,
0);

就是因为有未决操作,所以我要close啊,如果有未决就不能close,那不是死循环了?
myy 2009-12-09
  • 打赏
  • 举报
回复
要注意在还存在未决操作时,“完成端口句柄”绝对不能关闭,否则肯定都丢掉。
shenyi0106 2009-12-09
  • 打赏
  • 举报
回复
WSASend有返回值的,如果是SOCKET_ERROR
通过WSAGetLastError获得错误代码,如果是ERR_IO_PEEDING的话,那就能够保证数据入队了
awjx 2009-12-09
  • 打赏
  • 举报
回复
怎样判断WSASend是否投递成功呢?
这个成功是指成功入队,理论上可以被GET到事件了,而不是指数据发送成功!

shenyi0106 2009-12-09
  • 打赏
  • 举报
回复
返回了,Get函数返回FALSE的,你需要检查错误原因
dinona 2009-12-09
  • 打赏
  • 举报
回复
是否有将客户的Socket与完成端口关联起来,
一般情况绝对是会返回的.
javaaaaaaa 2009-12-09
  • 打赏
  • 举报
回复
这样是不太可靠,我之前也碰到这样的问题,导致线程池线程全被锁定了。后来在close之前等待所有WSASend请求全部返回再关闭就好了。
awjx 2009-12-09
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 yinshisike 的回复:]
引用 1 楼 awjx 的回复:
补充:原文说维持在2个左右,也许会有人怀疑是因为不断在send,所以存在大量未决事件。
我在观察到这个现象后,我使程序不再投递WSASend,也就是说,如果某个连接存在2个未决事件后不再往这个连接WSASend,很长时间或永远,或close该连接后,那2个未决事件一直都没有返回。




返回了,只不过完成状态是"错误".
[/Quote]

也就是说,close后,并不能通过ByteTransferred == 0来判断返回,而是GET失败表示close的返回吗?
awjx 2009-12-09
  • 打赏
  • 举报
回复
是保持了一个wsarecv,但我说的未决事件是send的,我为每个连接发送与发送完成使用了一个计数器,这个计数器没有记录wsarecv的未决...
vincent_1011 2009-12-09
  • 打赏
  • 举报
回复
服务器不是保持投递wsarecv的吗?
yinshisike 2009-12-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 awjx 的回复:]
补充:原文说维持在2个左右,也许会有人怀疑是因为不断在send,所以存在大量未决事件。
我在观察到这个现象后,我使程序不再投递WSASend,也就是说,如果某个连接存在2个未决事件后不再往这个连接WSASend,很长时间或永远,或close该连接后,那2个未决事件一直都没有返回。


[/Quote]

返回了,只不过完成状态是"错误".
awjx 2009-12-09
  • 打赏
  • 举报
回复
我一共发了两帖,那里可以发200分,谢谢了。
http://topic.csdn.net/u/20091209/13/0594ef65-5ae2-4c4e-a30d-2565f6f49387.html
awjx 2009-12-09
  • 打赏
  • 举报
回复
有些人也许会说应该保持一个IO请求,其实如果一个的话,也会存在一个IO永远未决的情况。所以我觉得保存几个IO请求与本问是无关,暂不讨论吧。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧