Netty的TCP粘包、拆包问题之FixedLengthFrameDecoder

Netty如何驾驭TCP流式传输?粘包拆包问题全解与编解码器最佳实践 其实上述的问题的原因都是因为TCP是面向流的协议,导致了数据包无法被正常切割成一个个正常数据包的流。就以上面的数据包为例,发送的数据为如果发送的数据都是以结尾,那我们的分割时就判断收到的流是否包含,只有包含时再将数据装成数据包发送。上述发送的数据长度为19,我们也可以规定发送的数据长度为19字节,一旦收到的数据达到19个字节之后,就组装成一个数据包。 阅读详情
上一篇说到Netty在处理TCP粘包拆包问题的三种解决方案。消息定长、分隔符和自定义协议(消息头和消息体),也给分隔符一个例子了,现在下面我们就弄一个消息定长的例子和说一下需要注意的地方。
详细代码就不放了,代码和上个例子的是一样的。
1.1、首先用到定长解码器服务端是在childHandler方法的初始化通道方法里面
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
//设置定长字符串接收(5个长度)
sc.pipeline().addLast(new FixedLengthFrameDecoder(5));
//设置字符串形式的编码
sc.pipeline().addLast(new StringEncoder());
//设置字符串形式的解码,以后在Handler那里获取的msg就是String类型的了。
sc.pipeline().addLast(new StringDecoder());
sc.pipeline().addLast(new ServerHandler()); //配置具体数据接收方法的处理器
}
});

1.2、然后修改ServeHandler的channelRead方法。
因为定长是五个长度嘛,那我们先试一下只发长度为3的看看,定长解码器会怎么处理。
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//因为配置了字符串形式的解码,所以msg会是String类型
String data = (String)msg;
System.out.println("Server接收到的数据:"+data);
//服务器给客户端返回数据
String str = "fff";
ctx.writeAndFlush(str);
}

1.3、客户端的初始化通道的方法也是要改为定长解码器。
//绑定事件处理器
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
//设置定长字符串接收
sc.pipeline().addLast(new FixedLengthFrameDecoder(5));
//设置字符串形式的编码
sc.pipeline().addLast(new StringEncoder());
//设置字符串解码
sc.pipeline().addLast(new StringDecoder());
sc.pipeline().addLast(new ClientHandler());
}
});
1.4、ClientHandler就不用改了,只是将服务端发送的数据直接打印出来而已。我们需要改的是客户端发送数据的代码。
定长是5,那么我们测试发长度为15的,看服务器的定长解码器是怎么处理的
cf.channel().writeAndFlush("aaaaabbbbbccccc"); //15个长度

1.5、执行结果:
服务端的:
Server接收到的数据:aaaaa
Server接收到的数据:bbbbb
Server接收到的数据:ccccc
小结:可以看到,客户端就算是发的是15个长度的数据,但是服务端还是每次只接收5个,将15个长度的分为三次接收。但是需要注意,就算分为三次接收,也只是一次通信。所以服务端只会返回一次数据。
客户端:
Client接收到的数据:fffff
小结:虽然服务端只是发了三个长度的数据,但是客户端接收到的还是5个长度的数据,定长解码器帮它补全了。但是有一个猜测,这里因为全部是字符f,所以补全也是补f,那如果是abc呢。下面做个测试。

2.1、服务端返回的数据改为abc:
String str = "abc";
ctx.writeAndFlush(str);

2.2、执行结果:
服务端:不变
Server接收到的数据:aaaaa
Server接收到的数据:bbbbb
Server接收到的数据:ccccc
客户端:重点观察
Client接收到的数据:abcab
小结:观察可得,补全的话,是从头拿然后补全,例如数据为三个长度,但是定长为五个长度,那么会从头拿数据的两个长度,然后到数据后面补全。例如 abc补全后abcab,edf补全后edfed。


总结:netty通信使用定长解码器的话,如果超长了会按定了的长度截取,如果不足的话,先取数据的前n位数据(n=定了的长度-数据长度),然后补在数据后面达到定了的长度
Netty4实战 - TCP粘包&拆包解决方案 阅读详情

相关推荐

Netty学习之固定长度解码器解决TCP粘包

FixedLengthFrameDecoder是固定长度解码器,它能够按照指定长度的长度对消息进行自动解码,开发者不需要考虑TCP粘包/拆包问题,非常实用。

3756

netty粘包拆包之FixedLengthFrameDecoder解码器

​目录 一、背景简介 二、应用 三、源码 一、背景简介 FixedLengthFrameDecoder固定长度解码器,他能够按照我们指定的固定长度(frameLength)对接收到的消息进行解码,如果我们接收到的消息字节数等于frameLength,则认为是一次完整的消息传输,如果我们接收到的消息字节数小于frameLength,则服务端在decode()处理的时候会返回null,所以客户端在传输数据的时候如果消息字节数小于frameL...

wenyixicodedog的博客 2516

Netty接收客户端数据,出现粘包,拆包问题解决办法(通俗易懂)

为什么只有TCP会发生粘包 TCP 是一个面向字节流的协议,它是性质是流式的,所以它并没有分段。就像水流一样,你没法知道什么时候开始,什么时候结束。 所以他会根据当前的套接字缓冲区的情况进行拆包或是粘包 举个栗子: 发送端发送了一个由2个100字节组成的200字节的数据包到服务端的缓冲区,接受端从缓冲去一次取80字节的数据,那么第一次取的就是一个不完整的数据包,第二次取就会带上第一个数据包的尾部和...

weixin_43993993的博客 3623

Netty学习之六—— 粘包/拆包 之 固定长度解码器FixedLengthFrameDecoder的应用

FixedLengthFrameDecoder 是固定长度解码器,它能够按照指定的长度对消息进行自动解码,开发者不需要考虑 TCP的粘包/拆包问题,非常实用。 客户端代码: package com.netty.echo; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.ByteBuf; import io....

ruanhao1203的专栏 845

netty学习二(解决tcp/udp 粘包,拆包问题)

在通讯协议中,粘包,拆包是常发生的事情,而netty则很好的给出了三种解决方式,下面分别介绍: 一;利用LineBasedFrameDecoder解决TCP粘包问题 直接上代码, Client类: package stickorApartPackageResolveOne.one; import io.netty.bootstrap.Bootstrap; import io.nett...

bird_tp的博客 2036

25年PINN创新点大盘点!

在科研论文的激烈角逐中,想轻松产出高含金量成果?物理信息神经网络(PINN)堪称“宝藏研究方向”,是冲击高分区论文的绝佳赛道!对于渴望发表优质论文的科研伙伴,这三大研究路径值得重点关注。首先是自适应PINN,在PINN训练过程中,物理方程与实测数据间的矛盾常常导致权重调节困难,而恰好直击这一痛点,是极具价值的研究方向。其次,同样前景广阔,传统多物理场同时训练效果欠佳,如今分阶段训练方法脱颖而出,成效显著且竞争较小。最后,探索及多任务学习等技术的融合,能实现优势叠加,碰撞出创新火花。

Malaai的博客 1970

netty之TCP粘包拆包问题解决

TCP粘包拆包问题解决 什么TCP粘包和拆包问题 假设客户端向服务端连续发送了两个数据包,分别用ABC和DEF来表示,那么服务端收到的数据可以分为以下三种情况: 第一种情况,接收端正常收到两个数据包,即没有发生拆包和粘包的现象。 第二种情况,接收端只收到一个数据包,这一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包。 第三种情况,接收端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种情况即发生了拆包和粘包。 为什么会发生TCP粘包和拆包 发生TCP粘包的原因:

morris 1万+

遗传算法详解 附python代码实现

遗传算法 遗传算法是用于解决最优化问题的一种搜索算法。从名字来看,遗传算法借用了生物学里达尔文的进化理论:”适者生存,不适者淘汰“,将该理论以算法的形式表现出来就是遗传算法的过程。 问题引入 上面提到遗传算法是用来解决最优化问题的,下面我将以求二元函数: def F(x, y): return 3*(1-x)**2*np.exp(-(x**2)-(y+1)**2)- 10*(x/5 - x**3......

ha_ha_ha233的博客 22万+

(十四)Netty的TCP粘包拆包问题

TCP是面向连接和流的协议,操作系统在TCP发送数据的时候会有一个缓冲区,在发送大数据块时将一个包拆分成多次较小的数据发送(拆包),在发送小数据包的时候且间隔时间较短,会将多个数据块合并到一个数据包中合并(粘包)。因为面向流通信无消息保护边界,导致接收端无法清晰的分辨出一个完整的数据包。 TCP的粘包拆分会导致几种情况的出现 假定发送数据包A B AB数据包都达到缓冲区大小,会分别发送2个单独的数据包发送 AB请求时间较短且AB的数据量较小,会将AB的数据合并和一个数据包发送出去 A数据大B数据小 A拆分

woshiwjma956的博客 305

解锁RK3588:内核模块签名与安全启动配置全攻略

RK3588作为一款高性能嵌入式SoC芯片,其内核模块签名与安全启动配置是保障系统安全的核心机制。本文详细介绍了RK3588的芯片特性,重点阐述了安全启动的硬件信任链原理和内核模块签名的实现方法。通过具体步骤演示了从密钥生成、模块签名到验证加载的完整流程,并深入解析了安全启动配置的硬件连接、软件工具准备、密钥烧录等关键环节。此外,还提出了防御旁路攻击和动态信任链扩展等高级安全策略,为RK3588在工业控制、智能安防等高安全要求场景中的应用提供了全面的安全解决方案。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 347

【Bug已解决】Codex 切换 model_provider 后历史会话消失的解决方案

方案适用场景推荐指数切回原 provider 验证排查的第一步,确认数据是否真的丢失⭐⭐⭐⭐⭐查看本地会话文件进一步确认数据完整性⭐⭐⭐⭐⭐查阅跨 provider 恢复命令官方是否提供了对应功能⭐⭐⭐使用社区辅助工具需要频繁切换 provider 的场景⭐⭐⭐定期备份配置目录任何场景下的通用保险措施⭐⭐⭐⭐切换后历史会话"消失"的本质是客户端的会话列表展示逻辑受当前活跃 provider 状态过滤,而不是原始数据文件被真正删除。

一键难忘的博客 6001

Netty 学习(七)常用的解码器

学习 Netty 常用的三种编码器: 固定长度编码器、特定分隔符编码器、长度域解码器等。

大鱼的博客 2456

EUV光源技术路线深度解析

EUV光刻技术的关键瓶颈在于13.5纳米光源的稳定高效获取。主流技术路线从DPP放电等离子体发展为LPP激光等离子体方案,后者通过激光轰击锡液滴实现更高功率输出。新出现的LDP技术综合激光预热与放电优势,虽功率扩展性有限,但为光源技术提供了有益补充。目前LPP仍是唯一通过量产验证的方案,而LDP可能作为过渡技术应用于特定场景。EUV光源的发展实质是能量转化效率与系统可靠性的持续优化过程,各种技术路线的探索共同推动着这一核心工艺的进步。

硬核科技 556

Netty 解决粘包和拆包问题的四种方案

Netty 解决粘包和拆包问题的四种方案

weixin_44749255的博客 5216

【项目实战】AES实施应符合NIST密码算法验证程序

AES由美国国家标准与技术研究院(NIST)制定。NIST是负责开发和维护美国政府使用的技术标准的机构,包括加密标准。

奶爸的编程之路,也就一周冷个三天 767

实战!C#整合YOLO+Halcon做玻璃瓶口缺陷检测:裂纹识别+尺寸测量一步到位(附DLL交互代码)

AI擅长语义识别(裂纹、缺陷),传统机器视觉擅长精密测量(尺寸、位置),C#做整合层,才能满足工业生产的“精度+效率+稳定性”要求。这套方案不只是玻璃瓶检测能用,改改模型和测量逻辑,还能用到瓶盖缺陷检测、饮料瓶液位检测等场景。如果你们厂也有类似的质检痛点,评论区留个言,我帮你看看怎么调整算法参数。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 870

Netty详解(五):Netty TCP粘包 拆包

1. 概述 无论是服务端还是客户端,我们读取或者发送消息的时候,都需要考虑TCP底层的粘包和拆包机制。下面我们来通过Netty来详解TCP底层的粘包和拆包机制。 2. TCP底层的粘包和拆包机制 TCP是一个“流”协议,所谓流,就是没有界限的一串数据。大家可以想想河里的水流,它们是连城有一片的,期间没有界限。TCP底层并不了解上层业务数据的具体含义,他会根据TCP缓冲区的实际情况进行包的划分,所以...

Master-TJ的个人博客 1667

【YoloV11改进策略】基于流形约束超连接(mHC)增强YoloV11全局特征提取能力|独家复现|梁文峰署名论文

论文标题:流形约束超连接 (Manifold-Constrained Hyper-Connections, mHC)核心问题:针对超连接 (Hyper-Connections, HC) 扩展残差流宽度时破坏恒等映射、引发训练不稳定性和高内存开销的问题,提出一种约束性框架。目标:恢复残差连接的稳定性与可扩展性,同时保持HC的性能增益。基准模型:基于DeepSeek-V3的MoE架构,进行了3B、9B、27B模型的实验验证。论文图示mHC 是一个通用的HC扩展框架。

m0_47867638的博客 1349

Netty解决粘包和拆包问题的四种方案

在RPC框架中,粘包和拆包问题是必须解决一个问题,因为RPC框架中,各个微服务相互之间都是维系了一个TCP长连接,比如dubbo就是一个全双工的长连接。由于微服务往对方发送信息的时候,所有的请求都是使用的同一个连接,这样就会产生粘包和拆包的问题。本文首先会对粘包和拆包问题进行描述,然后介绍其常用的解决方案,最后会对Netty提供的几种解决方案进行讲解。这里说明一下,由于oschina将“jie m...

weixin_34239169的博客 1130

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Netty如何解决粘包以及拆包问题

客户端与服务端进行`TCP`网络通信时,在发送以及读取数据时可能会出现粘包以及拆包问题,那么作为高性能网络框架的`Netty`是如何解决粘包以及拆包问题的呢?我们一起来探讨下这个问题。

4449

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Netty中粘包/拆包处理

TCP 是基于流传输的协议,请求数据在其传输的过程中是没有界限区分,所以我们在读取请求的时候,不一定能获取到一个完整的数据包。如果一个包较大时,可能会切分成多个包进行多次传输。同时,如果存在多个小包时,可能会将其整合成一个大包进行传输。这就是 TCP 协议的粘包/拆包概念。 本文基于 Netty5 进行分析 粘包/拆包描述 假设当前有123和abc两个数据包,那么他们传输情况示意图如下:...

YANGTAO_0的博客 1228

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Netty解决半包(TCP粘包/拆包导致)读写问题

摘要 使用Netty进行异步IO编程,同事问我粘包/拆包问题如何处理,所以抽空分析一下TCP粘包/拆包问题的产生;Netty提供了多种编解码器用于处理半包问题,熟练掌握了类库的应用,TCP粘包问题变得很容易。 TCP粘包/拆包 TCP是个"流"协议,所谓流,就是没有界限没有分割的一串数据。TCP会根据缓冲区的实际情况进行包划分,一个完整的包可能会拆分成多个包进行发送,也用可能把多

LANGZI7758521的专栏 1万+

什么是粘包和拆包,Netty如何解决粘包拆包?

基于以上问题,TCP层肯定是会出现当次接收到的数据是不完整数据的情况。发送方每次写入数据 < 套接字缓冲区大小;接收方读取套接字缓冲区数据不够及时。发送方每次写入数据 > 套接字缓冲区大小;发送的数据大于协议 MTU,所以必须要拆包。

Java技术江湖 1514

Netty 【2】 TCP粘包拆包

Netty TCP粘包拆包 熟悉tcp编程的可能都知道,无论是服务器端还是客户端,当我们读取或者发送数据的时候,都需要考虑TCP底层的粘包/拆包机制。 TCP是一个“流”协议,所谓流就是没有界限的遗传数据。大家可以想象下如果河里的水就好比数据,他们是连成一片的,没有分界线,TCP底层并不了解上层的业务数据具体的含义,它会根据TCP缓冲区的实际情况进行包的划分,也就是说,在业务上,我们一个完整的包可能会被TCP分成多...

qiu7213的博客 637

Netty 中的粘包和拆包详解

Netty 中的粘包和拆包

深圳市多克创新科技有限公司 3722

TCP粘包/拆包与Netty解决方案

【1】TCP粘包/拆包 TCP是个“流”协议,所谓流,就是没有界限的一串数据。大家可以想象河里的流水,它们是连成一片的,其间并没有分界线。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。 ① TCP粘包/拆包问题说明...

小小默:进无止境 5873
上一篇: NIO编程之三次握手成功而服务器不响应客户端
下一篇: 在前端如何使用jquery.storageapi.min.js缓存数据
Howinfun
博客等级 码龄10年 165粉丝 213原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值