李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
05.NIO之bytebuffer黏包和半包
Leefs
2022-05-26 PM
750℃
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
43
标签云
BurpSuite
Python
Redis
工具
VUE
Kibana
Java工具类
DataWarehouse
JavaWeb
线程池
Java
Jenkins
哈希表
Spark RDD
Map
MyBatis
Thymeleaf
数学
随笔
查找
Quartz
MyBatis-Plus
MyBatisX
并发线程
高并发
栈
Netty
Docker
链表
Jquery
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞