@Rookie
2020-07-01T17:14:14.000000Z
字数 1237
阅读 735
找工作
Socket通信时会对发送的字节数据进行分包和粘包处理,属于一种Socket内部的优化机制。
粘包:
当发送的字节数据包比较小且频繁发送时,Socket内部会将字节数据进行粘包处理,既将频繁发送的小字节数据打包成 一个整包进行发送,降低内存的消耗。
分包:
当发送的字节数据包比较大时,Socket内部会将发送的字节数据进行分包处理,降低内存和性能的消耗。
两个包在很短的时间间隔内发送,比如在0.1秒内发送了这两个包,如果包长度足够的话,那么接收方只会接收到一个包,如下:
123456789ABCDEFGH
假设包的长度最长设置为5字节(较极端的假设,一般长度设置为1000到1500之间),那么在没有粘包的情况下,接收方就会收到4个包,如下:
12345
6789
ABCDE
FGH
因为存在粘包和分包的情况,所以接收方需要对接收的数据进行一定的处理,主要解决的问题有两个:
比如在数据包的头部加上“START”字符串,尾部加上"END"字符串,这样可以解析出START和END之间的字符串就是接收方需要接收的内容。(当然真正处理的时候不可能使用START和END这种混效率较高的字符串,此处只是个例子)
上边两个包的例子就可以如下:
START123456789END
STARTABCDEFGHEND
发送方在发送的时候就可以在包头加上包的长度,接收方每次接收的时候都根据头部的长度去获取后面的内容。
上边两个包的例子就可以如下:
PACKAGELENGTH:0009123456789
PACKAGELENGTH:0008ABCDEFGH
START123456789ENDSTARTABCDEFGHEND
获取第一个START和第一个END的位置,然后获取他们之间的内容,第二个包的内容就是获取第二个START和第二个END的位置。
START123456789END
每个包要判断最后是否是END结尾,如果没有找到END,那么就保留上一个包START之后的内容,与下一个包第一个END之前的内容组合。
PACKAGELENGTH:0009123456789PACKAGELENGTH:0008ABCDEFGH
获取“PACKAGELENGTH:”这个字符串后面4个字符,转化为数字就是包的长度,根据包的长度获取后面的内容,第二个内容的长度就是获取第二个“PACKAGELENGTH:”字符串后面的4个字符。
PACKAGELENGTH:0009123456789
获取“PACKAGELENGTH:”这个字符串后面4个字符,转化为数字就是包的长度,如果包结尾还没有获取完,那么就要获取下一个包前面的部分内容。