为了账号安全,请及时绑定邮箱和手机立即绑定

socket 编程中的粘包问题

socket 编程中的粘包问题

慕虎7371278 2019-05-23 18:05:47
关于粘包,查了一些资料,还是不太清楚。我的理解是,A与B的连接建立后,socket将tcp字节流中的非数据字段进行拆解,并将数据部分放入该连接的输入缓冲区。当有多个A->B的包发来、且B没有对每一条数据及时进行处理时,多条信息就会同时存在于输入缓冲区中,首尾相连。如果数据部分没有分隔符或能够标识数据长度的字段,则很有可能出现无法分割出单条数据边界的情况,从而导致「粘包」。如果确实会出现「粘包」现象,则解决方法是不是应该是:确保接收方会及时处理发送来的数据,使输入缓冲区中同时只会存在一条发送来的数据;保证发送端的数据中有分隔符或能够标识其长度的字段(如HTTP消息)。不知道以上的理解是不是有误?
查看完整描述

2 回答

?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

理解的没啥问题,解决方案建议不要依赖于发送的数据一定能够被立即处理,而是从下面的角度出发:
比如只发送定包长数据,接收端判断长度即可。或者在包头中加入当前包的长度信息
添加边际分割字符串(但是要注意文本中本身可能包含的可能性)
                            
查看完整回答
反对 回复 2019-05-23
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

首先,需要明确什么是tcp中的粘包问题(具体可wiki),我这里大致描述下:tcp粘包就是指在tcp的网络编程(当然不止tcp,其他粘包也差不多意思)中,由于tcp是流式的,tcp提供给应用层的接口,无法获知发送端一次发了多少数据,也没办法获知发送端发了多少数据,就造成下一次数据头紧跟着上上一次数据尾,直接提供给应用层,应用层无法感知何处是发送端一次发送的边界。
下面说一下tcp粘包具体的原因:是发送端tcp层可能会对数据封装成多个tcp段,不仅如此,还会对应用层的多次数据组成一个包,比如应用层第一次写'A',第二次写'B',第三次写'C',在Tcp层很可能是发送一个tcp段,包含的数据是'ABC',所以,这样不管是接收端是否一次读一个tcp段,都无法分辨出哪里是发送端应用层边界,俗称"粘包"。
好,下面就简单说一下楼主(主要的错误也就1点):图片描述
如我上面所说,接收端以如何的方式处理都不是粘包的根本原因,因此,接收端一次读一个tcp段也是会造成粘包现象,从而到处严重的错误。
那么如何解决粘包:被采纳的答案的两条建议都是正确的,不过第一条容易让人引起误会,以为tcp可以一次读出定长的数据。没什么好办法,就是应用层自己设置协议解决粘包问题,最典型的就是采用协议头部和数据的方式。注意的是,这里应该用状态机实现接收端的功能,因为你不能确定发送端发了完整的头部,你就一定能收到完整的头部。
最简单的办法就是设置8个字节的头部,表示数据长度,接着就是数据。那么发送端先发送8个字节的一个数字,表示接下来的数据大小是多少,接着将数据全部发送过去。接收端一直接受数据,一直等到接受满了8个数据,取出来,计算出大小(假设为n),接着继续读取n个字节,就是完整的一个应用层的包了。
                            
查看完整回答
反对 回复 2019-05-23
  • 2 回答
  • 0 关注
  • 427 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号