0%

TCP粘包和拆包

TCP粘包和拆包

TCP是面向连接的,面向流的,提供了高可靠性服务,客户端和服务器端都要有一一成对的socket,因此,发送端为了将多个发给接收端的包,更有效的发给对方,使用优化方法(Nagle算法),将多次间隔较少且数据量小的数据,合并成一个大的数据块,然后进行封包,这样做虽然提高了效率,但是接收端就难于分辨出完整的数据包了,因为面向流的通信是无消息保护边界的,所以需要在接收端处理消息边界问题,也就是粘包和拆包问题

粘包产生的原因

  • 操作系统在发送TCP的时候,底层会有一个缓冲区,如果一次请求发送的数据量比较小,没达到缓冲区大小,TCP会将多个请求合并为一个请求进行发送

拆包产生的原因

  • 应用程序write写入的字节大小超过套接字发送缓冲区的大小
  • 进行MSS大小的TCP分段
  • 以太网帧的payload大于MTU进行IP分片

解决方法

根本就是解决就是服务器端每次读取长度的问题

有三种方案

  • 消息定长,如果不够,空位补空格 netty中使用的是FixedLengthFrameDecoder来实现定长
  • 在包尾部增加特殊字符进行分割 netty中使用了分隔符类DelimiterBasedFrameDecoder来实现分隔符分隔的
  • 将消息分为消息头和消息体,在消息头中包含表示消息总长度的字段,然后进行业务逻辑的处理 netty中使用的是LengthFieldPrepender进行编码,LengthFieldBasedFrameDecoder进行解码