目录
一. 粘包问题
二. 解决方案
一. 粘包问题
TCP面向字节流的传输方式,是导致出现粘包问题的原因,也可以说只要是面向字节流的传输方式都会出现粘包问题
- 发送方发送数据(我是大好人),这段数据肯定先存储在缓冲区,接收方通过使用read方法,从缓冲区读取出数据,应用层将数据转换成应用层数据包,才能被正确使用
- 发送方发送的TCP数据报,可能是多个应用层数据包,也可能是一个完整的应用数据包,也有可能是半个应用层数据包
- 应用层调用read读取数据,由于面向字节流,读取过程很灵活,可以读取出“我是”,也可以读取出“我是大好”
这种多个应用层数据包混淆不清的现象,就是粘包问题
发送方多次写入的数据可能在接收方被一次性读取(合并),或单次写入的数据被拆分成多次接收(拆包)。
二. 解决方案
这里解决的关键,就是明确包之间的边界
(1)使用符号作为分隔符
这里使用符合不能是随便使用,保证使用的符号不会在正式的数据中出现,当看见这个符号的时候,就视为一个包结束了
(2)指定包的长度
在包开始的地方,加上一个特殊的空间表示整个数据的长度
接收方通过先读取包头中的长度信息,再按该长度读取完整包体数据,从而解决粘包问题。
- 发送方在发送数据的时候,指定发送数据的长度,接收方从缓冲区读取数据的时候,会先读取报头的长度信息,然后根据长度信息,取出数据并封装成应用层数据包
- 如果长度信息是10字节,但是只有8字节数据,那么会陷入阻塞等待,等待哪个数据的到达,如果等待超时,可能会丢弃已经接收的8字节并抛出异常
粘包问题虽然是TCP引起的,但是操作系统内核并不会解决问题,需要程序员在应用层自己解决,其实使用应用层协议的格式(xml,json)就可以解决粘包问题