TCP粘包和拆包是怎么回事

都说粘包拆包的凶手是TCP?

粘包拆包的凶手是TCP吗

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。

出现所谓的 “粘包”,是应用层协议没有处理好数据包分割导致的。“粘包”和“拆包”其实是应用程序中没有处理好数据包分割,两个的数据包粘在一块或者一个数据包被分开。但是,T TCP本身是面向字节流的,以字节为单位,没有包这个概念。TCP会把你的数据变成字节流发到对面去,而且保证顺序不会乱,但是你要自己搞定字节流解析。解决好“发送方应该以什么格式发送数据,接收方能正确解析出数据“,就解决了“粘包”,这实际上是应用层协议的设计。

案发现场复现

Snipaste_2020-04-15_12-02-49.png

第一种情况:如上图中的第一根bar所示,服务端一共读到两个数据包,每个数据包都是完成的,并没有发生粘包的问题,这种情况比较好处理,服务器只需要简单的从网络缓冲区去读就好了,每次服务端读取到的消息都是完成的,并不会出现数据不正确的情况。

第二种情况:服务端仅收到一个数据包,这个数据包包含客户端发出的两条消息的完整信息,这个时候基于第一种情况的逻辑实现的服务端就蒙了,因为服务端并不能很好的处理这个数据包,甚至不能处理,这种情况其实就是TCP粘包问题。

第三种情况:服务端收到了两个数据包,第一个数据包只包含了第一条消息的一部分,第一条消息的后半部分和第二条消息都在第二个数据包中,或者是第一个数据包包含了第一条消息的完整信息和第二条消息的一部分信息,第二个数据包包含了第二条消息的剩下部分,这种情况其实是发送了TCP拆包问题,因为发生了一条消息被拆分在两个包里面发送了,同样上面的服务器逻辑对于这种情况是不好处理的。

作案动机

粘包

  1. 应用程序写入的数据小于套接字缓冲区大小,网卡将应用多次写入的数据发送到网络上,这将会发生粘包。
  2. 接收方法不及时读取套接字缓冲区数据,这将发生粘包。

拆包

  1. 应用程序写入的数据大于套接字缓冲区大小,这将会发生拆包。
  2. 进行MSS(单个报文最大长度)大小的TCP分段,当 TCP报文长度-TCP头部长度>MSS 的时候将发生拆包。

预防犯罪

  1. 使用带消息头的协议、消息头存储消息开始标识及消息长度信息,服务端获取消息头的时候解析出消息长度,然后向后读取该长度的内容。
  2. 设置定长消息,服务端每次读取既定长度的内容作为一条完整消息,当消息不够长时,空位补上固定字符。
  3. 设置消息边界,服务端从网络流中按消息边界分离出消息内容,一般使用‘’。

参考链接

作者:李晓峰 链接:https://www.zhihu.com/question/20210025/answer/1096399109 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

TCP 粘包问题浅析及其解决方案

TCP粘包,难道说这是一个伪命题???

TCP 粘包问题浅析及其解决方案


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!