TCP粘包

为什么说 TCP 是面向字节流的协议,UDP 是面向报文的协议?

原因在于两者发送方的机制不同,UDP 传输时,系统不会对报文进行拆分,在封装好 UDP 头部后就会交给网络层,所以发出去的 UDP 报文就是完整的一个消息,也就是每个 UDP 报文就是一个消息的边界。而 TCP 协议则会对发出消息拆分成多个报文,如果接收方不知道发送方的消息长度,就不知道消息的边界,无法读取有效的消息,因此 TCP 传输不能认为一个用户消息对应一个 TCP 报文,所以说 TCP 是面向字节流的协议。

当两个消息的部分内容被分到同一个 TCP 报文,就出现了粘包,这时接收方不知道消息的边界的话,无法读出有效的消息。解决方式在于如何分包,确定消息边界。一般有三种方式分包的方式:

  • 固定长度的消息:每个消息长度固定,但该方式灵活度不高
  • 特殊字符作为边界:两个用户消息之间插入特殊字符,如果刚好消息内容里有这个特殊字符,那么要在发送时对这个字符转义,避免被接收方当作消息的边界点而解析到无效的数据。
  • 自定义消息结构:我们可以自定义一个消息结构,由包头和数据组成,其中包头包是固定大小的,而且包头里有一个字段来说明紧随其后的数据有多大。
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计