李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
05.NIO之bytebuffer黏包和半包
Leefs
2022-05-26 PM
1130℃
0条
[TOC] ### 一、示例 > 网络上有多条数据发送给服务端,数据之间使用 \n 进行分隔 > 但由于某种原因这些数据在接收时,被进行了重新组合,例如原始数据有3条为 * Hello,world\n * I'm zhangsan\n * How are you?\n 变成了下面的两个 byteBuffer (黏包,半包) * Hello,world\nI'm zhangsan\nHo * w are you?\n **分析** 本来分别将上方三条数据发送给服务端,但是发送到服务的却是两条 + 第一条数据中的第二行和第三行中的Ho当作一条数据发送给了服务端,产生了**黏包**。 + 第二条数据,因为服务端并未接收到完整的第三条数据,所以产生了**半包**。 ### 二、黏包和半包出现原因 + **黏包** > 发送方在发送数据时,并不是一条一条地发送数据,而是**将数据整合在一起**,当数据达到一定的数量后再一起发送。这就会导致多条信息被放在一个缓冲区中被一起发送出去 + **半包** > 接收方的缓冲区的大小是有限的,当接收方的缓冲区满了以后,就需要**将信息截断**,等缓冲区空了以后再继续放入数据。这就会发生一段完整的数据最后被截断的现象 ### 三、代码示例 #### 解决方案 - 通过get(index)方法遍历ByteBuffer,遇到分隔符时进行处理。注意:get(index)不会改变position的值 - 记录该段数据长度,以便于申请对应大小的缓冲区 - 将缓冲区的数据通过get()方法写入到target中 - 调用**compact方法**切换模式,因为缓冲区中可能还有未读的数据 ``` import java.nio.ByteBuffer; import static com.lilinchao.nio.bytebuffer_2.ByteBufferUtil.debugAll; /** * Created by lilinchao * Date 2022/5/26 * Description 黏包和半包 Demo */ public class TestByteBufferExam { public static void main(String[] args) { ByteBuffer buffer = ByteBuffer.allocate(32); // 模拟黏包 buffer.put("Hello,world\nI'm zhangsan\nHo".getBytes()); split(buffer); //模拟半包 buffer.put("w are you?\nhaha!\n".getBytes()); split(buffer); } private static void split(ByteBuffer buffer){ //切换到读模式 才能从buffer中读取数据 buffer.flip(); int oldLimit = buffer.limit(); for (int i=0;i
标签:
Netty
,
NIO
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/2090.html
上一篇
04.NIO之bytebuffer常见方法演示
下一篇
06.NIO之FileChannel介绍
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
MyBatis
MyBatisX
Golang
Jenkins
Golang基础
Jquery
Flink
字符串
Typora
Sentinel
CentOS
MyBatis-Plus
Spark Streaming
序列化和反序列化
Thymeleaf
ClickHouse
Hbase
Tomcat
递归
FileBeat
栈
ajax
Java工具类
NIO
持有对象
锁
SpringBoot
Nacos
VUE
Quartz
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭