有一次面试被问道TCP"粘包"问题, 当时还有点蒙, 这什么玩意? 啥是粘包?

这其实是个人体验上感觉数据粘在一起了, 从这个现象上也反映出tcp的一些特性

问题原因

就不说老生常谈的三次握手,四次挥手的流程. 首先要明确一点就是tpc是一种"流"式协议, 就像水一样, 两边的水管对接好, 数据就吨吨吨得从水管中流过…

而且由于是全双工的, 两端不中断就一直连着, 那两头的缓冲区就一直存在, 缓冲区的数据你不及时清理掉自然会有问题

比如AB端建立连接后, A 第一次发送了 “hello”, 第二次发送了 “world”, 但是一二次之间没有push操作, 全在发送缓冲区里面屯着, 等到缓冲区满了自动发送, 那B接收的时候自然是一条"helloworld”, 没有明显的断点标识, 在B端就认为是一条数据了, 这就是所谓的"粘包”

同理来说B端的接收端也一样, A连着发了两条数据, B因为在处理别的事情没忙过来, 等他反应过来的时候发现缓冲区躺着的就像一条数据一样…

像基于tcp的http协议, 人家是发一次就关闭连接, 这自然就不会出现粘包的问题

如何避免

  1. 从发送端来说, 需要及时清理发送缓存区的数据, 比如使用tcp提供的强制push指令
  2. 在接收端的角度来说, 需要提升接收进程的优先级, 及时清理掉接收缓存区的数据
  3. 从数据的角度来说, 要么发送的数据块都一样的尺寸, 要么就设计个数据结构, 头部标明数据尺寸, 或者有明显的终结字符比如\n啥的

参考