有关网络组包问题。

love514425 2010-04-13 08:43:06
> 自定义了一套协议,本地收到服务器的组包的不一定有序,这时该采取什么方案比较好?
比如当包1来了后,可能下一个是包4,然后包3,包2 这样子的,我要把这些包组合好后写入文件(这些包在远处本身就是一个文件拆开来发的)。请有做个这方面的兄弟给点意见!小弟谢了先。
...全文
332 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
品茶识书香 2010-05-05
  • 打赏
  • 举报
回复
我也刚刚问完这个问题,不过现在明白了 ,就是定义一个包头,然后把包头的每个字段序列化成二进制的BIT流,存在char数组里。然后把头发出去,然后在把数据发过去。。。大概 就是这样。
etz2008 2010-04-26
  • 打赏
  • 举报
回复
很简单
序列化
Un1 2010-04-26
  • 打赏
  • 举报
回复
那你就固定包大小,比如每个包1024字节,收到那个包就直接seek并write到文件的偏移1024x编号处。说白了文件先写前面还是后面无关紧要。
TRUE 2010-04-14
  • 打赏
  • 举报
回复
一个包结构,包含序列号以及大小和数据内容。
收到包后,seek文件的位置,然后写入size大小的数据。
love514425 2010-04-14
  • 打赏
  • 举报
回复
>顶一下。
love514425 2010-04-14
  • 打赏
  • 举报
回复
> 这个问题已经解决,谢谢大家。
love514425 2010-04-14
  • 打赏
  • 举报
回复
好像LZ有点晕, 你每个包有300K, 怎么了啊, 排序又不是对300K的每个字节排序。
另外GPRS怎么了啊, 又不是每个包都收多次, 占什么GPRS啊。接受的数据量是一定的。
建议如下:
(1)每个包里面都要有(包序号, 包的总数)
(2)接受到每个包都先放到一个LIST里面(只放指针), 如果接受到的包的数量=包总数,就开始排序(仅仅是包序号的排列)。
当然你也可以每次放到LIST里面时,做排序插入。那么最后就是逐个取出就可以了。
===============================================================================================
1 排序又不是对300K的每个字节排序。 没错,排序不对300K字节,但是得根据相应的排序结果移动这300K字节啊。
要不然排序有什么意义呢? 光排序包序号有什么用?
2 你仔细看看4楼哥们的回复,他的意思是在发送的没个包里面,加上headmark(头标识),tailmark这些字段,这是没必要的,在走GPRS传输的时候,包里面的每一个字节都得仔细考虑,因为要考虑到一个流量问题,尽可能的节省流量,再加上GPRS本身的传输速率相对而言比较慢,不同与普通的网络传输.
3 每个包里面都要有(包序号, 包的总数) ,包数据大小。 嗯,这个没错,我们的协议就是这样设计的。
wenfengsoftware 2010-04-14
  • 打赏
  • 举报
回复
做下补充,如果你是接受文件。 把文件在一定大小分成N个包就可以了。
每个包里面还要有个(包数据大小)的标示。
接受到以后,按照包总数,包序号,每个包的大小重新拼装。
wenfengsoftware 2010-04-14
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 love514425 的回复:]
引用 4 楼 muyiyj 的回复:
我觉得可以采取rtp的方式来弄
你将私有协议封装在一个结构体内部,在结构体中另定义seq(序列号),headmark(头标识),tailmark(尾标识)。
你对收到的包根据seq来排序,然后根据headmark和tailmark来还原被分割的包

哥们,我一个包有300K,这样子排序性能消耗比较大啊。 而且像你所说的话,没一个包都要seq(序列号)……
[/Quote]
好像LZ有点晕, 你每个包有300K, 怎么了啊, 排序又不是对300K的每个字节排序。
另外GPRS怎么了啊, 又不是每个包都收多次, 占什么GPRS啊。接受的数据量是一定的。
建议如下:
(1)每个包里面都要有(包序号, 包的总数)
(2)接受到每个包都先放到一个LIST里面(只放指针), 如果接受到的包的数量=包总数,就开始排序(仅仅是包序号的排列)。
当然你也可以每次放到LIST里面时,做排序插入。那么最后就是逐个取出就可以了。
xhp7185 2010-04-13
  • 打赏
  • 举报
回复
路过~~~~~~~~~
Eleven 2010-04-13
  • 打赏
  • 举报
回复
收到包后,如果序号不正确,可以放在一个链表中,链表中的数据包要按序号从小到大插入,可以参考IOCP中的分包组包
love514425 2010-04-13
  • 打赏
  • 举报
回复

嗯,2楼兄弟的方式我也考虑过,就是想看看还没有更好了解决方案。
还有,在我的包里面,有两个字节已经表示了包的编号.
muyiyj 2010-04-13
  • 打赏
  • 举报
回复
我觉得可以采取rtp的方式来弄
你将私有协议封装在一个结构体内部,在结构体中另定义seq(序列号),headmark(头标识),tailmark(尾标识)。
你对收到的包根据seq来排序,然后根据headmark和tailmark来还原被分割的包
lmxmx 2010-04-13
  • 打赏
  • 举报
回复
发送文件时,除了最后一个包,其他包可以设置相同的大小,然后设置包序号。

接收后,将包序号作为写文件的指针偏移,可以临时解决该问题。

想根治的话,就必须使用可靠传输协议……
jason176374 2010-04-13
  • 打赏
  • 举报
回复
UDP啊?TCP没这个问题吧。

如果一定要组的话,2楼兄弟是正解
田暗星 2010-04-13
  • 打赏
  • 举报
回复
呵呵,思路倒是有的..

你客户端 先获取 服务器端 文件大小 size

客户端生成一个大小为 size的文件【占位而已】

包肯定是有固定大小的了,根据包的顺序 计算相对 size的偏移量 填充即可
【注意记录 已经填充好的包,完成后 检查记录,判断文件是否接收完毕】
这样就不怕包乱序了,也不怕丢包,能检查是否成功..
Wenxy1 2010-04-13
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 scq2099yt 的回复:]

每个包都一个序号,收全后组包
[/Quote]
支持。
wuhuwy 2010-04-13
  • 打赏
  • 举报
回复
不懂,友情帮顶
  • 打赏
  • 举报
回复
简单!
首先定义一个数组指针a,数组大小为一共的可能收到多少包,并初始化为全0。
当收到包2时,先包2存在内存中,用一个指针指向他,将数组a[2-1]=包2指针,当收到包4时,将数组a[4-1]=包4指针,以此类推。
在收包的同时,创建一个计数器,收一个包,递加依次,一共记录收到了多少个包。
当计数器达到应该收的包个数时,说明数据包全部收完,根据数组指针的内容依次写入文件。OK!
Jasonshengxi 2010-04-13
  • 打赏
  • 举报
回复
1 客户端缓冲接收包序列;
2 包内容应包含包号,以及分割包偏移号
3 设置超时,以及重发
4 拥塞控制
加载更多回复(4)

18,356

社区成员

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

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