各位大侠:我写的服务器遇到一个这样的问题;
1.我在发送数据的时候,在打好数据包后我用PostQueuedCompletionStatus通知工作线程处理发送消息。
2.工作线程接收到消息,将步骤1中写入队列的数据buffer取出, 并调用WSASend写数据包到发送缓存。即调用我的OnSendBegin函数。
3.接着,完成端口接收到响应--缓冲数据发送完成消息,同时我会在此时释放从队列中取出的缓存buffer。即调用我的OnSendEnd函数。但就是在这个流程中,如果我在接收到一条数据后,连续的向Client直接进行发送多条数据(我测试的是5条)。然后我强行断掉client端(就在这种情况下才出现),这时候会出现OSendBegin与OnSendEnd的发送前,与发送后的次数不一致(这时我是不关闭socket的,服务器会一直等待,OSendBegin投递的数据都被OnSendEnd执行完成后才关闭socket)。但发现会出现两种情况:
1)OnSendBegin的执行次数比OnSendEnd执行次数多一次。也就是OnSendBegin执行了n,但OnSendEnd执行n-1次,而造成内存池中的一块内存不被释放。(这个频繁出现)
2)OnSendEnd的执行次数比OnSendBegin执行次数多一次。也就是OnSendEnd执行了n,但OnSendBegin执行n-1次,而造成内存池中的一块内存计数被释放两次。(这个出现但不频繁)为什么呢?完成端口为什么没有或多投递OnSendEnd呢?我没有清除Socket的缓存也没有关闭Socket啊。这种情况如何解决呢?
1.我在发送数据的时候,在打好数据包后我用PostQueuedCompletionStatus通知工作线程处理发送消息。
2.工作线程接收到消息,将步骤1中写入队列的数据buffer取出, 并调用WSASend写数据包到发送缓存。即调用我的OnSendBegin函数。
3.接着,完成端口接收到响应--缓冲数据发送完成消息,同时我会在此时释放从队列中取出的缓存buffer。即调用我的OnSendEnd函数。但就是在这个流程中,如果我在接收到一条数据后,连续的向Client直接进行发送多条数据(我测试的是5条)。然后我强行断掉client端(就在这种情况下才出现),这时候会出现OSendBegin与OnSendEnd的发送前,与发送后的次数不一致(这时我是不关闭socket的,服务器会一直等待,OSendBegin投递的数据都被OnSendEnd执行完成后才关闭socket)。但发现会出现两种情况:
1)OnSendBegin的执行次数比OnSendEnd执行次数多一次。也就是OnSendBegin执行了n,但OnSendEnd执行n-1次,而造成内存池中的一块内存不被释放。(这个频繁出现)
2)OnSendEnd的执行次数比OnSendBegin执行次数多一次。也就是OnSendEnd执行了n,但OnSendBegin执行n-1次,而造成内存池中的一块内存计数被释放两次。(这个出现但不频繁)为什么呢?完成端口为什么没有或多投递OnSendEnd呢?我没有清除Socket的缓存也没有关闭Socket啊。这种情况如何解决呢?
解决方案 »
- 在MFC对话框中,有些资源可以直接双击打开,有些却不可以,为啥?
- CListCtrl添加数据界面变化,删除数据界面不变?Tab+Alt后才变
- VC++6.0里没有自动匹配功能吗?
- PDFlib的设置问题
- 俩段代码返回指针问题。
- 怎样给多维数组动态分配内存?
- 大家认为我有必要花一万元去读"北大青鸟"的第二学年的课程么?犹豫~~~~~~~~~~
- ADO访问access出错,哪位大哥帮帮忙...
- VB和VC的混合编程中如何实现将VC的大批量数据回传VB?
- 50分求购windows sdk 开发包国内下载地址。微软那里下不了了。
- 如何自定义属性表的按钮事件?并修改按钮名称,比如"应用"改变名字,并加入自
- SetTimer如何进行处理????
OnSendEnd
.....
如果你在断开client端时,OnSendBegin()被执行了,但数据还是在系统缓冲中,还没有全部发送到client端的话,你的第三步自然没有被执行到(因为没有完全发送完毕的消息,OnSendEnd()自然就没被执行到),那么OnSendEnd比OnSendBegin少一次并不是奇怪事.