iocp关于收包疑问?
本帖最后由 oyljerry 于 2012-07-23 11:24:43 编辑 假定IOCP有2个线程 分别是A B
客户1发送 "head!123!充值100!end"(数据很大 )
客户1发送 "head!456!充值200!end"(数据很大 )
在数据比较大的情况会不会出现:
IOCP A线程收到“head!123!” 一半的数据? 另一半数据让B线程收到? (数据很大的情况下)
我习惯得到数据包后 判断是否有end如果没有就进行组包 我怕出现“head!123!充值200end!"
[最优解释]
不要在同一个套接字上投递多个recv!
服务器的任务不是尽快的响应某个套接字,而是尽量不要太慢的平均的响应每一个套接字。
你多线程recv,不会比单recv快多少。却带来编程的复杂(复杂度远超你想象),因为你收到的包可能完全是乱序的,不光是加个序号组包这么简单,因为还涉及到分包粘包问题(比如一个包,被两个线程收到,你怎么组)。另外,你组包时还得加解锁。
无论你有多少个线程去同时recv,可是网线只有一根,所以根本没用,你只要做到,每次recv到数据的时候,马上拷贝到缓存中,再继续recv,处理逻辑在另外的线程中,从缓存中取数据,然后处理(这是网络编程中服务端基本原则,但CSDN上问问题的人,没见有人遵守过),就不会有效率上的损失。
服务端网络编程其实本质上只做数据在用户与内核之间的拷贝,瓶颈在逻辑处理。
[其他解释]
有可能,每个包加个序号,然后组包。
[其他解释]
利用IOCP投递Recv时可以指定completeKey,通过不同的completeKey可以区分不同的客户。
[其他解释]
带大名顶顶的boost.asio来说,你可以看看它的代码:
boost/asio/write.hpp: 416
的async_write函数的说明,明确指出,用户必须保证,在投递一个async_write之后一直到数据发送完毕,这之间不允许再次投递另一个async_write。
[其他解释]
不仅会出现断包(分几包收)的问题, 还可能会出现,后面的包先收的问题,如A线程收前半包, 后半包B线程收, 还可能会出现B线程先接收完的问题
完成端口有这个问题, 得自己想办法解决
[其他解释]
弄成短连接吧,充值一次就断开。
[其他解释]
不推荐在一个socket上投递多个recv,因为投递多个recv势必要由多个线程去处理,线程间的同步和互斥就成了关键问题,反而复杂了。
我的理解是:在每个socket上仅投递一个recv,接收完数据后再投递recv,这样就不用考虑乱序的问题,也就不会出现“head!123!充值200end!”这种情况。
6楼说的现象可能是由于投递多个recv引起的。
[其他解释]
如果是客户端顺序发送,服务器端每次仅投递一个recv,那么TCP的连接会在底层保证数据包的内部顺序,iocp仅仅是一种io模型,iocp所做的工作仅仅是通知应用程序 数据来了或者数据发送出去了,之所以乱序是因为应用程序多线程从socket buffer中取数据造成的。如果楼主是逐次投递recv,从理论上讲,应该没问题。
[其他解释]
IOCP的 WSAsend和WSArecv还是建议一次投递一个IO请求,这样处理起来简单
[其他解释]
学习来了!
[其他解释]
1,看楼上对客户端套接字投递了几次 revc 如果每次收到数据后 才投递下一个的话,就不需要加什么序号
2,如果楼上 在收到 数据之前,投递了 2次以上的 recv 则需要进行 投递序号的处理,否则出现“包的乱序”现象
[其他解释]
不是区分客户的问题
那个客户1是销售代理 他发送指令给谁充值的指令 出现 “head!123!充值200end!”
给用户123冲200那就悲剧了