粘包:即多个数据首尾连接在一起。TCP协议使用流的方式向缓冲区写入数据,发送包时,包太小且缓冲区未满,就可能多个包合并一起发送,造成粘包;在接收数据时,如果缓冲区的数据未及时处理,也会造成粘包。
分包:即接收到的数据只是发送的一部分。IP分片传输、传输过程中丢包、包被分成多次传输、缓冲区大小等造成。
解决方式:为每个数据库添加边界,将数据封包
1、用分隔符的方式,在数据结尾添加特定字符
当接收数据时,根据结尾符将包分开;如果包中没有找到结尾符,则先缓存数据,继续读取数据,直到出现结尾符。这种方式适合文本的传输,且要对数据中的结尾符进行转义。
2、数据前边添加特定字符和数据的长度。
起始符 数据长度 数据
比如起始符为$$,包长为int类型4个字节,即包头长度为6个字节。
【1】当接收数据时,先判断包长,如果不够6个字节,先将数据缓存起来,下次处理的时候,将缓存与读取的数据合并再解析包;
【2】读取2个字节,如果等于起始符"$$",继续读取4个字节即数据的长度L,如果包剩余的数据长度<L,即为半包,保存起来,下次处理的时候先填充半包;如果包剩余长度=L,表示一个完整的包;如果剩余长度>L,表示有粘包,继续从头处理。
代码
1、定义数据结构

注意:我这里使用了protbuf-net对数据作了标识,以便后边使用protobuf序列化。protobuf序列化比.net二进制序列化效率更高,序列化后的数据要小很多。
2、定义半包结构

3、封包处理,在发送数据时,先对数据进行封包

4、解包,即接收数据时解包,处理粘包和半包

解包调用

文章转载自不想做程序员,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




