粘包
什么是粘包?
须知:只有TCP有粘包现象,UDP永远不会粘包
粘包不一定会发生
如果发生了:
1.可能是在客户端已经粘了
2.客户端没有粘,可能是在服务端粘了
我在其他地方看到两种解释:
应用程序所看到的数据是一个整体,或说是一个流(stream),一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因。
数据粘包问题的出现,是因为在客户端/服务器端都会有一个比较大的数据缓冲区,来存放接收的数据,为了保证能够完整的接收到数据,因此缓冲区都会设置的比较大。在收发数据频繁时,由于tcp传输消息的无边界,会导致客户端/服务器端不知道接收到的消息到底是第几条消息,因此,会导致类似一次性接收几条消息的情况,从而乱码。
总的来说,就是 客户端/服务器端 根本不知道你一串消息有多长,就像一个说话含糊不清的朋友跟你讲话,他如果不慢慢说,你就无法正确的断句。
粘包发生的两种情况:
1、发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据量很小时,会当做一个包发出去,产生粘包) 2、接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)
问题的根源在于,接收端不知道发送端将要传送的字节流的长度,所以解决粘包的方法就是围绕,如何让发送端在发送数据前,把自己将要发送的字节流总大小让接收端知晓,然后接收端来一个死循环接收完所有数据。
一种就是用特定的暗号截断,比方说:“完毕!”这种的,让人知道哪句是哪句。 另一种就是将消息的长度作为消息的一部分发送出去(包头)
代码可以参考这份博客:数据粘包处理