tcp粘包,半包处理,两种方法更好些,请教各位大侠

skyclosed 2010-12-30 09:01:25
第一种是 发送消息之前,将消息打包,包头中添加该消息的字符长度,接收方接受消息之后根据包头字符长度来判定是否是整包。
第二种是 发送消息之前,将消息打包,包头中添加一个标识符,作为每个包开头的标识,包尾作同样处理。然后将除包头包尾的数据部分出现包头、包尾标识的数据进行转义。接收方通过真正的包头和包尾确定是否是整包,然后去除转义字符。

就是这两种方法了,不知道描述的清楚不清楚。
下面有请各位大侠指点下 这两种方法在效率(即分包的速度)和安全(取的包是否为真正的包)方面的优劣。
...全文
579 26 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
skyclosed 2010-12-31
  • 打赏
  • 举报
回复
好了,到此结贴了。非常感谢各位的帮忙~~~
  • 打赏
  • 举报
回复
recv的时候对返回值做个判断,recv的参数是接收缓冲区的长度,返回值是实际接收的长度,实际接收的可能小于缓冲区的长度。

这时候要判断有没有收完,没有收完继续收。
白虹李李 2010-12-30
  • 打赏
  • 举报
回复
第一种方式一般用于TCP/IP这类的网络应用。
第二种方式也很常见,用于嵌入式或者比较低端的非WINDOWS编程,在这种情况下,包与包之间的标识符一般是由硬件产生的,不用人去处理。转义也是由硬件来进行的。
萧山夜雨 2010-12-30
  • 打赏
  • 举报
回复
绝大部分时候,做应用都可以采用包的定长设计.编程简单,,比如把包设计为1024字节,收端简单的除以1024,就知道是几个包了.
skyclosed 2010-12-30
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 fishion 的回复:]
引用 3 楼 skyclosed 的回复:
引用 1 楼 visualeleven 的回复:
自定义协议,包头长度+数据,第一种比较好,
第二种的话,数据中存在包尾的标示的问题。

第一种的话,接收端通过长度判定,如果没有一个包开始的标志,是不是存在不知道从哪里开始计算长度

没有包长度,你就不知道该接收多少数据了
[/Quote]

是啊,如果包头找错了,那么长度肯定也错了,因为长度是在包头中的,那后面的解析就全错了
这不是鸭头 2010-12-30
  • 打赏
  • 举报
回复
一直使用第二种方式
skyclosed 2010-12-30
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 bragi523 的回复:]
第一种办法直观一些

第二种你需要,接收多一些,再判断分包的话,效率会高一点
[/Quote]

像一般的网络数据传输,如果需要包带有结构,会用那一种?考虑安全多一点的话
skyclosed 2010-12-30
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hastings 的回复:]
第一次接收到,就说明是包头啊~~~~
然后弄个循环,一直接受第一个包,直到长度达到包头里面指定的长度,
那么接下去的就是第二个包呀~~~
[/Quote]

是这样的,我也是这么想的。但是如果出现问题,那么只要中间有一个包解析错了,那后面的肯定全错。
照理说tcp是基于连接的,传来的数据应该不会有问题。 那么有没有程序跑偏了的可能。使得出现中间某个包解析错误。
bragi523 2010-12-30
  • 打赏
  • 举报
回复
第一种办法直观一些

第二种你需要,接收多一些,再判断分包的话,效率会高一点
fishion 2010-12-30
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 skyclosed 的回复:]
引用 1 楼 visualeleven 的回复:
自定义协议,包头长度+数据,第一种比较好,
第二种的话,数据中存在包尾的标示的问题。

第一种的话,接收端通过长度判定,如果没有一个包开始的标志,是不是存在不知道从哪里开始计算长度
[/Quote]
没有包长度,你就不知道该接收多少数据了
hastings 2010-12-30
  • 打赏
  • 举报
回复
第一次接收到,就说明是包头啊~~~~
然后弄个循环,一直接受第一个包,直到长度达到包头里面指定的长度,
那么接下去的就是第二个包呀~~~
skyclosed 2010-12-30
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 i03630211 的回复:]
应该第1种快,第2种要你不停的判断每个发送过来的数据是不是结束符或者转义后的字符。
安全性应该差不多吧
[/Quote]

我是这样做的,开辟一段足够大的内存,在接收的时候,把接收来的数据全放到这块内存里,然后对这块内存里的数据进行拆包操作,如果出现半包,不处理,等下次接收来数据后拼接到半包的后面,继续拆包。

我想说的是,在拆包的时候,通过长度判定是否为整包,那么没有一个开始的标志,怎么知道从哪里开始算起
skyclosed 2010-12-30
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 visualeleven 的回复:]
自定义协议,包头长度+数据,第一种比较好,
第二种的话,数据中存在包尾的标示的问题。
[/Quote]
第一种的话,接收端通过长度判定,如果没有一个包开始的标志,是不是存在不知道从哪里开始计算长度
还在查 2010-12-30
  • 打赏
  • 举报
回复
应该第1种快,第2种要你不停的判断每个发送过来的数据是不是结束符或者转义后的字符。
安全性应该差不多吧
Eleven 2010-12-30
  • 打赏
  • 举报
回复
自定义协议,包头长度+数据,第一种比较好,
第二种的话,数据中存在包尾的标示的问题。
大蓝头 2010-12-30
  • 打赏
  • 举报
回复
第一种吧!
covsno 2010-12-30
  • 打赏
  • 举报
回复
TNND
TCP粘包,我去
这个提法不知道那个垃圾说出来的
以前也被它耽误过

其实楼主你直接看看HTTP协议的报文格式会死吗?
teleinfor 2010-12-30
  • 打赏
  • 举报
回复
再补充一点,TCP是可靠传输协议,可以保证"接收到"的数据是不会出现和发出方不一致的。所以你的所谓的HCS校验想法完全没有必要!这是TCP协议干的事情。
b2b160 2010-12-30
  • 打赏
  • 举报
回复
用第一种,然后在包里面的数据有数据头啊,数据头如果错了就close socket让客户端断掉.
就不会有太大问题啦.
teleinfor 2010-12-30
  • 打赏
  • 举报
回复
啥粘包?没搞懂你们说啥啊。TCP是面向字节的流式传输,至于每个TCP segment的数据长度和内容界定,都需要应用层自己定义的。你这里如果需要判断接收的数据字节长度,当然需要自己定义一个格式了。

HEAD + DATA是必须的方式。HEAD内包含有对data长度和类型的说明。接收时候按照这个格式解析即可。

啥粘包不粘包的,在通信领域没有这个术语,不知道是哪位programmer发明的?!误人子弟啊。
加载更多回复(6)

18,363

社区成员

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

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