IOCP多次投递问题,初学IOCP,请大大们指导下,谢谢

zhuben775 2016-07-12 04:03:16

服务器发送文件给客户端时需要多次连续投递WSASend,投递是没有问题,问题是当所有数据发送完毕后,如何将该客户端变为只有一个WSARecv模式。

我断点时发现,当我循环WSASend后,多个线程的GetQueuedCompletionStatus会同时处理WSASend,我的想法是在最后一次WSASend后投递一个WSARecv,但根本不知道如何去实现,请大大们指导一下吧,谢谢
...全文
203 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhuben775 2016-07-15
  • 打赏
  • 举报
回复
引用 9 楼 shenyi0106 的回复:
[quote=引用 7 楼 zhuben775 的回复:] [quote=引用 5 楼 shenyi0106 的回复:] [quote=引用 3 楼 zhuben775 的回复:] [quote=引用 2 楼 shenyi0106 的回复:] WSARecv完成后投递下一个WSARecv就行了,干嘛要让WSASend完成后投递下一个WSARecv?? 逻辑关系不怎么对啊
我接受到WSARecv后要发送消息 WSASend(pIoContext->sSockAccept,&(pIoContext->sWsaBuf),1,&SendBytes,0,&(pIoContext->sOverlapped),NULL); 然后直接? WSARecv( pIoContext->sSockAccept, &pIoContext->sWsaBuf, 1, &dwBytes, &dwFlags, &pIoContext->sOverlapped, NULL ); 这样不对啊,消息根本没发出去,GetQueuedCompletionStatus处理的的状态是最后的POSTED_RECV,之前的POSTED_SEND被覆盖了啊[/quote] 要修改Context中的标志啊PostRead,PostWrite标志啊![/quote] 我知道修改标志,但是在一个线程的处理中,因为是同一个重叠IO所以前面改的OSTED_SEND状态被后面的POSTED_RECV状态给覆盖了,我在网上看说是send和recv是需要分开建两个重叠IO的?是需要这样的吗?[/quote] 肯定要分开的,难不成你send和recv公用一个缓冲区??你recv下去就会被系统锁定,在用就崩掉了啊[/quote] 貌似只有一个缓冲区。。。
shenyi0106 2016-07-14
  • 打赏
  • 举报
回复
引用 7 楼 zhuben775 的回复:
[quote=引用 5 楼 shenyi0106 的回复:] [quote=引用 3 楼 zhuben775 的回复:] [quote=引用 2 楼 shenyi0106 的回复:] WSARecv完成后投递下一个WSARecv就行了,干嘛要让WSASend完成后投递下一个WSARecv?? 逻辑关系不怎么对啊
我接受到WSARecv后要发送消息 WSASend(pIoContext->sSockAccept,&(pIoContext->sWsaBuf),1,&SendBytes,0,&(pIoContext->sOverlapped),NULL); 然后直接? WSARecv( pIoContext->sSockAccept, &pIoContext->sWsaBuf, 1, &dwBytes, &dwFlags, &pIoContext->sOverlapped, NULL ); 这样不对啊,消息根本没发出去,GetQueuedCompletionStatus处理的的状态是最后的POSTED_RECV,之前的POSTED_SEND被覆盖了啊[/quote] 要修改Context中的标志啊PostRead,PostWrite标志啊![/quote] 我知道修改标志,但是在一个线程的处理中,因为是同一个重叠IO所以前面改的OSTED_SEND状态被后面的POSTED_RECV状态给覆盖了,我在网上看说是send和recv是需要分开建两个重叠IO的?是需要这样的吗?[/quote] 肯定要分开的,难不成你send和recv公用一个缓冲区??你recv下去就会被系统锁定,在用就崩掉了啊
zhuben775 2016-07-14
  • 打赏
  • 举报
回复
引用 6 楼 xian_wwq 的回复:
iocp的流程基本围绕数据投递进行,不管是连接,还是读,写,都需预先投递; 什么时候读,什么时候写,其实是由业务层的定义确定的 比如业务层需要收到客户端的身份验证信息,那就需要根据验证信息定义的长度,进行读投递。
恩,这个我明白,我的意思是我收到一个消息后,需要连续投递写信息,但是投递完这些写信息后,再投递一个读,就是这块整不明白了,不知道该怎么写代码了
zhuben775 2016-07-14
  • 打赏
  • 举报
回复
引用 5 楼 shenyi0106 的回复:
[quote=引用 3 楼 zhuben775 的回复:] [quote=引用 2 楼 shenyi0106 的回复:] WSARecv完成后投递下一个WSARecv就行了,干嘛要让WSASend完成后投递下一个WSARecv?? 逻辑关系不怎么对啊
我接受到WSARecv后要发送消息 WSASend(pIoContext->sSockAccept,&(pIoContext->sWsaBuf),1,&SendBytes,0,&(pIoContext->sOverlapped),NULL); 然后直接? WSARecv( pIoContext->sSockAccept, &pIoContext->sWsaBuf, 1, &dwBytes, &dwFlags, &pIoContext->sOverlapped, NULL ); 这样不对啊,消息根本没发出去,GetQueuedCompletionStatus处理的的状态是最后的POSTED_RECV,之前的POSTED_SEND被覆盖了啊[/quote] 要修改Context中的标志啊PostRead,PostWrite标志啊![/quote] 我知道修改标志,但是在一个线程的处理中,因为是同一个重叠IO所以前面改的OSTED_SEND状态被后面的POSTED_RECV状态给覆盖了,我在网上看说是send和recv是需要分开建两个重叠IO的?是需要这样的吗?
xian_wwq 2016-07-13
  • 打赏
  • 举报
回复
iocp的流程基本围绕数据投递进行,不管是连接,还是读,写,都需预先投递; 什么时候读,什么时候写,其实是由业务层的定义确定的 比如业务层需要收到客户端的身份验证信息,那就需要根据验证信息定义的长度,进行读投递。
shenyi0106 2016-07-13
  • 打赏
  • 举报
回复
引用 3 楼 zhuben775 的回复:
[quote=引用 2 楼 shenyi0106 的回复:] WSARecv完成后投递下一个WSARecv就行了,干嘛要让WSASend完成后投递下一个WSARecv?? 逻辑关系不怎么对啊
我接受到WSARecv后要发送消息 WSASend(pIoContext->sSockAccept,&(pIoContext->sWsaBuf),1,&SendBytes,0,&(pIoContext->sOverlapped),NULL); 然后直接? WSARecv( pIoContext->sSockAccept, &pIoContext->sWsaBuf, 1, &dwBytes, &dwFlags, &pIoContext->sOverlapped, NULL ); 这样不对啊,消息根本没发出去,GetQueuedCompletionStatus处理的的状态是最后的POSTED_RECV,之前的POSTED_SEND被覆盖了啊[/quote] 要修改Context中的标志啊PostRead,PostWrite标志啊!
zhuben775 2016-07-13
  • 打赏
  • 举报
回复
引用 1 楼 cvbtvbwu 的回复:
将WSASend发送的包都存储到链表里,GetQueuedCompletionStatus处理WSASend时,把对应的WSASend发送的包移除链表,如果链表为空则投递一个WSARecv
如何判断链表是否为空?另外,多个SEND是多线程同时处理的,这个地方不做多线程互斥的话,判断链表为空是不准确的吧
zhuben775 2016-07-13
  • 打赏
  • 举报
回复
引用 2 楼 shenyi0106 的回复:
WSARecv完成后投递下一个WSARecv就行了,干嘛要让WSASend完成后投递下一个WSARecv?? 逻辑关系不怎么对啊
我接受到WSARecv后要发送消息 WSASend(pIoContext->sSockAccept,&(pIoContext->sWsaBuf),1,&SendBytes,0,&(pIoContext->sOverlapped),NULL); 然后直接? WSARecv( pIoContext->sSockAccept, &pIoContext->sWsaBuf, 1, &dwBytes, &dwFlags, &pIoContext->sOverlapped, NULL ); 这样不对啊,消息根本没发出去,GetQueuedCompletionStatus处理的的状态是最后的POSTED_RECV,之前的POSTED_SEND被覆盖了啊
shenyi0106 2016-07-13
  • 打赏
  • 举报
回复
WSARecv完成后投递下一个WSARecv就行了,干嘛要让WSASend完成后投递下一个WSARecv?? 逻辑关系不怎么对啊
叶恭介叶恭介 2016-07-12
  • 打赏
  • 举报
回复
将WSASend发送的包都存储到链表里,GetQueuedCompletionStatus处理WSASend时,把对应的WSASend发送的包移除链表,如果链表为空则投递一个WSARecv
1、本课程是一个干货课程,主要讲解如何封装服务器底层,使用Tcp/ip长连接,IDE使用vs2019 c++开发以及使用c++11的一些标准,跨平台windows和linux,服务器性能高效,单服务器压力测试上万无压力,服务器框架是经历过上线产品的验证,框架简单明了,不熟悉底层封装的人,半个小时就能完全掌握服务器框架上手写业务逻辑。2、本课程是一个底层服务器框架教程,主要是教会学员在windows或linux下如何封装一个高效的,避免踩坑的商业级框架,服务器底层使用初始化即开辟内存的技术,使用内存池,服务器运行期间内存不会溢出,非常稳定,同时服务器使用自定义哈希hashContainer,在处理新的连接,新的数据,新的封包,以及解包,发包,粘包的过程,哈希容器性能非常高效,增、删、查、改永远不会随着连接人数的上升而降低性能,增、删、查、改的复杂度永远都是恒定的O(1)。3、服务器底层封装没有使用任何第三方网络库以及任何第三方插件,自由度非常的高,出了任何BUG,你都有办法去修改,查找问题也非常方便,在windows下使用iocp,linux下使用epoll.4、讲解c++纯客户端,主要用于服务器之间通信,也就是说你想搭建多层结构的服务器,服务器与服务器之间使用socket通信。还可以使用c++客户端做压力测试,开辟多线程连接服务器,教程提供了压力测试,学员可以自己做压力测试服务器性能。5、赠送ue4和unity3d通信底层框架以及多人交互demo,登录,注册,玩家离开,同步主要是教会学员服务器与客户端如何交互。6、赠送c++连接mysql数据库框架demo,登录,注册,玩家离开数据持久化.7、服务器教程使用自定义通信协议,同时也支持protobuf,选择权在开发者自己手里,想用什么协议都可以,自由度高。8、服务器教程使用手动敲代码逐句讲解的方式开展教学课程。非喜勿喷,谢谢大家。9、服务器教程提供源码,大家可以在平台提供的地址下载或者联系我,服务器使用c++11部分标准,std::thread,条件变量,线程锁,智能指针等,需要学员具备一定c++知识,购买前慎重考虑。

18,356

社区成员

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

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