美文网首页
粘包和分包

粘包和分包

作者: SpursGo | 来源:发表于2017-03-29 13:55 被阅读105次

搬运过来的,方便以后查

1.粘包产生原因

  • TCP:由于TCP协议本身的机制(面向连接的可靠地协议-三次握手机制)客户端与服务器会维持一个连接(Channel),数据在连接不断开的情况下,可以持续不断地将多个数据包发往服务器,但是如果发送的网络数据包太小,那么他本身会启用Nagle算法(可配置是否启用)对较小的数据包进行合并(基于此,TCP的网络延迟要UDP的高些)然后再发送(超时或者包大小足够)。那么这样的话,服务器在接收到消息(数据流)的时候就无法区分哪些数据包是客户端自己分开发送的,这样产生了粘包;服务器在接收到数据库后,放到缓冲区中,如果消息没有被及时从缓存区取走,下次在取数据的时候可能就会出现一次取出多个数据包的情况,造成粘包现象(确切来讲,对于基于TCP协议的应用,不应用包来描述,而应该用流来描述)。

  • UDP:本身作为无连接的不可靠的传输协议(适合频繁发送较小的数据包),他不会对数据包进行合并发送(也就没有Nagle算法之说了),他直接是一端发送什么数据,直接就发出去了,既然他不会对数据合并,每一个数据包都是完整的(数据+UDP头+IP头等等发一次数据封装一次)也就没有粘包一说了。

2.分包产生的原因

  可能是IP分片传输导致的,也可能是传输过程中丢失部分包导致出现的半包,还有可能就是一个包可能被分成了两次传输,在取数据的时候,先取到了一部分(还可能与接收的缓冲区大小有关系),总之就是一个数据包被分成了多次接收
Paste_Image.png

3.粘包和分包的解决方法

  • 一个是采用分隔符的方式,即我们在封装要传输的数据包的时候,采用固定的符号作为结尾符(数据中不能含结尾符),这样我们接收到数据后,如果出现结尾标识,即人为的将粘包分开,如果一个包中没有出现结尾符,认为出现了分包,则等待下个包中出现后 组合成一个完整的数据包,这种方式适合于文本传输的数据,如采用/r/n之类的分隔符。
  • 另一种是采用在数据包中添加长度的方式,即在数据包中的固定位置封装数据包的长度信息(或可计算数据包总长度的信息),服务器接收到数据后,先是解析包长度,然后根据包长度截取数据包(此种方式常出现于自定义协议中),但是有个小问题就是如果客户端第一个数据包数据长度封装的有错误,那么很可能就会导致后面接收到的所有数据包都解析出错(由于TCP建立连接后流式传输机制),只有客户端关闭连接后重新打开才可以消除此问题,我在处理这个问题的时候对数据长度做了校验,会适时的对接收到的有问题的包进行人为的丢弃处理(客户端有自动重发机制,故而在应用层不会导致数据的不完整性)

相关文章

  • 10.Netty框架-Netty编程模板(编解码和粘包拆包)

    一、什么是分包/粘包 二、分包/粘包的原因 三、分包/粘包的解决方案 四、Netty内置的分包/粘包的处理器 1、...

  • 粘包和分包

    搬运过来的,方便以后查 1.粘包产生原因 TCP:由于TCP协议本身的机制(面向连接的可靠地协议-三次握手机制)客...

  • 即时通讯

    iOS即时通讯,从入门到“放弃”?socket的半包,粘包与分包的问题iOS 处理socket粘包问题iOS___...

  • iOS客户端与java后台 socket通信

    1. socket需要解决粘包和分包问题 1.1什么是分包? socket一次性传输的数据大小是有限制的,当有数据...

  • NodeJs中TCP粘包、分包解决方案!

    NodeJs中TCP粘包、分包解决方案! 最新更新请查看github项目配置介绍 本类库提供对TCP粘包处理的解决...

  • 27.粘包分包处理

    1.Server 2.MyServerInitializer 3.ServerHandler 4.Client

  • 文章收藏

    iOS native 加载 H5 图片(沙盒加载html图片) socket的半包,粘包与分包的问题 Scoket...

  • mpvue小程序分包

    小程序本着轻便,即来即用的原则,所以小程序要求一个包(主包和分包)小于2M才能预览和发布,如果分包所有的包(主包和...

  • TCP分包粘包问题解决

  • netty的粘包与分包的处理

    1、netty在进行字节数组传输的时候,会出现粘包和分包的情况。当个数据还好,如果数据量很大。并且不间断的发送给服...

网友评论

      本文标题:粘包和分包

      本文链接:https://www.haomeiwen.com/subject/mxieottx.html