iocp关于收包疑问?

EvilGene 2012-07-21 07:54:10
假定IOCP有2个线程 分别是A B
客户1发送 "head!123!充值100!end"(数据很大 )
客户1发送 "head!456!充值200!end"(数据很大 )

在数据比较大的情况会不会出现:

IOCP A线程收到“head!123!” 一半的数据? 另一半数据让B线程收到? (数据很大的情况下)

我习惯得到数据包后 判断是否有end如果没有就进行组包 我怕出现“head!123!充值200end!"
...全文
257 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
luawkk 2012-09-06
  • 打赏
  • 举报
回复
1,看楼上对客户端套接字投递了几次 revc 如果每次收到数据后 才投递下一个的话,就不需要加什么序号
2,如果楼上 在收到 数据之前,投递了 2次以上的 recv 则需要进行 投递序号的处理,否则出现“包的乱序”现象
「已注销」 2012-09-01
  • 打赏
  • 举报
回复
IOCP的 WSAsend和WSArecv还是建议一次投递一个IO请求,这样处理起来简单

ChinaTek 2012-09-01
  • 打赏
  • 举报
回复
学习来了!
翅膀又硬了 2012-07-30
  • 打赏
  • 举报
回复
弄成短连接吧,充值一次就断开。
zxd_0511 2012-07-30
  • 打赏
  • 举报
回复
如果是客户端顺序发送,服务器端每次仅投递一个recv,那么TCP的连接会在底层保证数据包的内部顺序,iocp仅仅是一种io模型,iocp所做的工作仅仅是通知应用程序 数据来了或者数据发送出去了,之所以乱序是因为应用程序多线程从socket buffer中取数据造成的。如果楼主是逐次投递recv,从理论上讲,应该没问题。
zxd_0511 2012-07-30
  • 打赏
  • 举报
回复
不推荐在一个socket上投递多个recv,因为投递多个recv势必要由多个线程去处理,线程间的同步和互斥就成了关键问题,反而复杂了。

我的理解是:在每个socket上仅投递一个recv,接收完数据后再投递recv,这样就不用考虑乱序的问题,也就不会出现“head!123!充值200end!”这种情况。

6楼说的现象可能是由于投递多个recv引起的。
youngwolf 2012-07-25
  • 打赏
  • 举报
回复
带大名顶顶的boost.asio来说,你可以看看它的代码:
boost/asio/write.hpp: 416
的async_write函数的说明,明确指出,用户必须保证,在投递一个async_write之后一直到数据发送完毕,这之间不允许再次投递另一个async_write。
youngwolf 2012-07-25
  • 打赏
  • 举报
回复
不要在同一个套接字上投递多个recv!

服务器的任务不是尽快的响应某个套接字,而是尽量不要太慢的平均的响应每一个套接字。

你多线程recv,不会比单recv快多少。却带来编程的复杂(复杂度远超你想象),因为你收到的包可能完全是乱序的,不光是加个序号组包这么简单,因为还涉及到分包粘包问题(比如一个包,被两个线程收到,你怎么组)。另外,你组包时还得加解锁。

无论你有多少个线程去同时recv,可是网线只有一根,所以根本没用,你只要做到,每次recv到数据的时候,马上拷贝到缓存中,再继续recv,处理逻辑在另外的线程中,从缓存中取数据,然后处理(这是网络编程中服务端基本原则,但CSDN上问问题的人,没见有人遵守过),就不会有效率上的损失。

服务端网络编程其实本质上只做数据在用户与内核之间的拷贝,瓶颈在逻辑处理。
MingoJ 2012-07-25
  • 打赏
  • 举报
回复
不仅会出现断包(分几包收)的问题, 还可能会出现,后面的包先收的问题,如A线程收前半包, 后半包B线程收, 还可能会出现B线程先接收完的问题
完成端口有这个问题, 得自己想办法解决
EvilGene 2012-07-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
利用IOCP投递Recv时可以指定completeKey,通过不同的completeKey可以区分不同的客户。
[/Quote]

不是区分客户的问题
那个客户1是销售代理 他发送指令给谁充值的指令 出现 “head!123!充值200end!”
给用户123冲200那就悲剧了
微型蚂蚁 2012-07-21
  • 打赏
  • 举报
回复
利用IOCP投递Recv时可以指定completeKey,通过不同的completeKey可以区分不同的客户。
Eleven 2012-07-21
  • 打赏
  • 举报
回复
有可能,每个包加个序号,然后组包。
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创作助手写篇文章吧