TCP粘包是什么?出现原因?怎样解决?UDP会粘包吗?
粘包就是多个连续的数据包被看成是同一个。
粘包出现有三个因素共同导致:
- 从http1.1开始,TCP连接都是长连接,一次连接里可以发送多个数据包
- TCP传输方式是基于字节流的,数据包没有边界(UDP有边界)
- 发送时,如果数据包过小,TCP协议默认启用Nagle算法,将连续的小数据包在缓冲区中合并。因此在发送之前粘包就出现了。
除此之外,接收方也会出现粘包:接收后放到缓冲区,如果取出顺序小于放入顺序,也会造成粘包。
解决方案:
- 增设包头,在包头首都添加数据包的长度属性。
- 固定数据包的长度。灵活性差,如果包内容不够,需要填充特殊的信息,如 \0;如果超出,又得分包。
- 以指定字符(串)作为数据包的结束标志。例如, FTP协议和 SMTP 协议,一个命令或者一段数据后面加上"\r\n"表示一个包的结束。
- 如果使用 netty 的话,有专门的编码器和解码器解决拆包和粘包问题。
UDP 传输方式是基于报文的,有边界,不会有粘包问题。但有丢包和乱序的可能,如果想避免,可以考虑RTP或RUDP协议。