拼多多面试:Netty如何解决粘包问题?

粘包和拆包问题也叫做粘包和半包问题,它是指在数据传输时,接收方未能正常读取到一条完整数据的情况(只读取了部分数据,或多读取到了另一条数据的情况)就叫做粘包或拆包问题。

从严格意义上来说,粘包问题和拆包问题属于两个不同的问题,接下来我们分别来看。

1.粘包问题

粘包问题是指在网络通信中,发送方连续发送的多个小数据包被接收方一次性接收的现象。这可能是因为底层传输层协议(如 TCP)会将多个小数据包合并成一个大的数据块进行传输,导致接收方在接收数据时一次性接收了多个数据包,造成粘连。

例如以下案例,正常情况下客户端发送了两条消息,分别为“ABC”和“DEF”,那么接收端也应该收到两条消息“ABC”和“DEF”才对,但是接收端却收到了“ABCD”这样的消息,这种情况就叫做粘包,如下图所示:

图片

2.拆包/半包问题

拆包问题是指发送方发送的一个大数据包被接收方拆分成多个小数据包进行接收的现象。这可能是因为底层传输层协议(如 TCP)将一个大数据包拆分成多个小的数据块进行传输,导致接收方在接收数据时分别接收了多个小数据包,造成拆开。

例如以下案例,客户端发送了一条消息“ABC”,而接收端却收到了“AB”和“C”两条信息,这种情况就叫做半包,如下图所示:

图片

PS:大部分情况下我们都把粘包问题和拆包问题看成同一个问题,所以下文就用粘包问题来替代粘包和拆包问题。

3.为什么会有粘包问题?

粘包问题通常发生在 TCP/IP 协议中,因为 TCP 是面向连接的传输协议,它是以“流”的形式传输数据的,而“流”数据是没有明确的开始和结尾边界的,所以就会出现粘包问题

4.常见解决方案

粘包问题的常见解决方案有以下 3 种:

  1. 固定大小方法:发送方和接收方固定发送数据大小,当字符长度不够时用空字符弥补,有了固定大小之后就知道每条消息的具体边界了,这样就没有粘包的问题了。

  2. 自定义数据协议(定义数据长度):在 TCP 协议的基础上封装一层自定义数据协议,在自定义数据协议中,包含数据头(存储数据的大小)和 数据的具体内容,这样服务端得到数据之后,通过解析数据头就可以知道数据的具体长度了,也就没有粘包的问题了。

  3. 特殊分割符:以特殊的字符结尾,比如以“\n”结尾,这样我们就知道数据的具体边界了,从而避免了粘包问题。

以上三种方案中,第一种固定大小的方法可能会造成网络流量的浪费,以及传输性能慢的问题;第二种解决方案实现难度大,且不利于维护,所以比较推荐的是第三种方案,使用特殊分隔符来区分消息的边界,从而避免粘包问题。

5.Netty解决方案

Netty 解决方案也延续了上面的常见解决方案,它的解决方案有以下几个:

  1. 使用定长解码器(FixedLengthFrameDecoder):每个数据包都拥有固定的长度,接收端根据固定长度对数据进行切分,从而解决了粘包问题。

  2. 使用行分隔符解码器(LineBasedFrameDecoder):以行为单位进行数据包的解码,从而解决粘包问题。

  3. 使用分隔符解码器(DelimiterBasedFrameDecoder):使用特定的分隔符来标识消息边界,这样接收端可以根据分隔符正确切分消息。

  4. 使用长度字段解码器(LengthFieldBasedFrameDecoder):在消息头部加入表示消息长度的字段,接收端根据长度字段来确定消息的边界,而从解决粘包问题。

PS:在 Netty 中,解码器(Decoder)起着非常重要的作用。解码器主要负责将从网络中接收到的原始字节流数据转换为应用程序能够理解的 Java 对象或消息格式。使用解码器可以解决粘包和拆包问题、协议转换问题、消息编码(如文本转换为字节流)等问题。

这些解码器的使用如下。

5.1 定长解码器

定长解码器(FixedLengthFrameDecoder)使用示例如下:

ChannelPipeline pipeline = ch.pipeline();
// 假设每条消息长度为 5
pipeline.addLast(new FixedLengthFrameDecoder(5)); 
pipeline.addLast(new StringDecoder());
pipeline.addLast(new YourBusinessLogicHandler());

5.2 行分隔符解码器

行分隔符解码器(LineBasedFrameDecoder)使用示例如下:

ChannelPipeline pipeline = ch.pipeline();
// 设置行分隔符解码器最大(帧)长度为 8192 字节
pipeline.addLast(new LineBasedFrameDecoder(8192)); 
pipeline.addLast(new StringDecoder()); // 添加字符串解码器
pipeline.addLast(new SimpleChannelInboundHandler<String>() {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {System.out.println("接收到消息:" + msg);}
});

5.3 分隔符解码器

分隔符解码器(DelimiterBasedFrameDecoder)使用示例如下:

ChannelPipeline pipeline = ch.pipeline();
// 使用 \r\n 来进行分隔
ByteBuf delimiter = Unpooled.copiedBuffer("\r\n".getBytes());
pipeline.addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
pipeline.addLast(new StringDecoder());
pipeline.addLast(new YourBusinessLogicHandler());

5.4 长度字段解码器

长度字段解码器(LengthFieldBasedFrameDecoder)使用示例如下:

ChannelPipeline pipeline = ch.pipeline();
// 设置最大帧长度为 1024 字节,长度字段位于第 0 个字节,长度字段占用 4 个字节
pipeline.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 4));
pipeline.addLast(new LengthFieldPrepender(4));
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast(new LengthFieldServerHandler());

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/23407.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全球AI新闻速递6.5

全球AI新闻速递 1.昆仑万维&#xff1a;开源2 千亿稀疏大模型天工Skywork-MoE&#xff0c;首个支持单台RTX 4090服务器。 2.字节豆包推出桌面客户端&#xff1a;支持 Windows / macOS&#xff0c;快捷启动、AI 划词、 AI 搜索。 3.东风柳汽与优必选科技签署人形机器人汽车制造…

FreeRTOS手表项目多级菜单的实现

一、首先介绍一下智能手表项目的背景&#xff1a; 如图&#xff0c;关注焦点是任务&#xff1a; 1、在一个确定时刻&#xff0c;在那一圈任务中&#xff08;写有只有一个任务解挂&#xff09;只有一个任务处在运行&#xff0c;界面显示的是该任务应该显示的内容&#xff1b; …

vscode运行Java utf-8文件中文乱码报错

问题现象 vscode 运行utf-8 java文,爆出如下错误 hello.java:5: &#xfffd;&#xfffd;&#xfffd;&#xfffd;: &#xfffd;&#xfffd;&#xfffd;&#xfffd;GBK&#xfffd;IJ&#xfffd;&#xfffd;&#xfffd;ӳ&#xfffd;&#xfffd;&#xfffd;ַ&a…

如何增加网站外链?

想增加网站外链&#xff0c;无非就是去其他别的网站不停去发带自己网站链接的内容&#xff0c;这取决于你去什么平台发&#xff0c;一般来说发外链无非就是几种方式 博客以及论坛&#xff0c;要能提供评论功能的&#xff0c;在这种平台积极发表评论&#xff0c;并在允许的情况…

DevOps在数字化转型中的作用——实现数字化可视性

DevOps 的出现是为了满足不断增长的市场和消费者对技术应用程序的需求。它旨在在不牺牲软件质量的情况下创建更快的开发环境。DevOps 还专注于在快速开发生命周期中提高软件的整体质量。它依赖于多种技术、平台和工具的组合来实现所有这些目标。 容器化是一项彻底改变了我们开发…

如何在桌面添加多个便签 怎样在桌面创建便签

每当我坐在电脑前&#xff0c;总会被各种琐事和灵感所困扰&#xff0c;需要一个随手可记、随时可查的工具。直到我发现了敬业签便签软件彻底改变了我的工作习惯。 她不仅可以在桌面上轻松创建多个便签&#xff0c;而且它的“云游”功能简直让我爱不释手。想象一下&#xff0c;…

http://account.battlenet.com.cn

http://account.battlenet.com.cn 魔兽战网 短信验证 查了下&#xff0c;我老早以前账号还在&#xff0c;纪念下&#xff0c;少玩游戏。

计算机网络学习记录 应用层 Day6

你好,我是Qiuner. 为记录自己编程学习过程和帮助别人少走弯路而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​ gitee https://gitee.com/Qiuner &#x1f339; 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 &#x1f604; (^ ~ ^) 想看更多 那就点个关注吧 我…

国产方案|轮胎气压胎压计方案

气压胎压计的基本原理是利用气压传感器将气体气压转换为电信号&#xff0c;再通过电子芯片电路进行处理传输&#xff0c;再将这些信息转发给显示屏显示。常见的传感器包括模拟气压传感器和数字气压传感器。其中&#xff0c;模拟气压传感器是目前应用最广泛的传感器之一&#xf…

2020 6.s081——Lab5:Lazy page allocation

再来是千年的千年 不变是眷恋的眷恋 飞越宇宙无极限 我们永不说再见 ——超兽武装 完整代码见&#xff1a;SnowLegend-star/6.s081 at lazy (github.com) Eliminate allocation from sbrk() (easy) 顾名思义&#xff0c;就是去掉sbrk()中调用growproc()的部分。1s完事儿。 Laz…

Mysql root用户远程连接失败解决方案

最近&#xff0c;踩坑云服务器通过root用户远程连接Mysql数据库失败&#xff0c;Mysql 版本为 5.7.44&#xff0c;原因如下&#xff0c;因为root用户权限过大&#xff0c;可能会有风险操作&#xff0c;可以新增其他用户来解决此问题&#xff0c;如果一定要用root用户&#xff0…

gitblit 环境搭建,服务器迁移记录

下载 Gitblit&#xff1a; http://www.gitblit.com/ JDK&#xff1a;gitblit网站显示需要jdk1.7&#xff0c;这里用的1.8。 Git&#xff1a;到官网下载最新版本安装 1). 分别安装JDK&#xff0c;Git&#xff0c;配置环境变量&#xff0c;下载并解压Gitblit 2). 创建代码仓库 …

阿里云镜像加速配置(工作中经常用到,写在此方便)

原因 由于运营商网络原因&#xff0c;会导致您拉取Docker Hub镜像变慢&#xff0c;甚至下载失败。为此&#xff0c;阿里云容器镜像服务ACR提供了官方的镜像加速器&#xff0c;从而加速官方镜像的下载。 获取镜像加速器地址 ACR会为每一个账号&#xff08;阿里云账号或RAM用户…

网络安全专用产品销售许可证查询的几种方式你知道吗?

随着网络技术的日益先进&#xff0c;网络安全事故也频发&#xff0c;因此购买网络安全专用产品&#xff0c;例如堡垒机是非常重要的。这里提醒大家要购买正规具有销售许可证的网络安全专用产品哦&#xff01;网络安全专用产品销售许可证查询的几种方式你知道吗&#xff1f; 网络…

农业收入管理实现高效策略:用友BIP收入云引领企业收款新篇章

农业收入管理的高效性对于农场或农业企业的成功至关重要。为实现高效的农业收入管理&#xff0c;可以考虑以下几点&#xff0c;并结合用友BIP收入云等工具来提升收款效率。 1. 精细化经营和现代化管理 了解土地和作物&#xff1a;农民应了解农场土地的类型和特点&#xff0c;合…

C#——break、continue、goto关键字的使用

break break是搭配循环语句使用的&#xff0c;用于跳出循环。 举例 : 当for循环执行到第5次时&#xff0c;使用break方法 跳出循环。 continue continue 语句的工作原理与 break 语句类似&#xff0c;但是 continue 语句并不会跳出整个循环&#xff0c;而是跳过本次循环继续执…

zabbix“专家坐诊”第241期问答

问题一 Q&#xff1a;华为交换机的100GE 1/0/1口的光模块收光值监测不到&#xff0c;有没有人碰到过这个问题呢&#xff1f;其他的端口都能监测到收光值&#xff0c;但是100GE 1/0/1口监测不到收光值。底层能查到&#xff0c;zabbix 6.0监控不到&#xff0c;以下是端口的报错信…

通过Dockerfile构建postgresql数据库镜像初始化表数据

通过Dockerfile构建postgresql数据库镜像初始化表数据 1.编写Dockerfile2.构建镜像 1.编写Dockerfile #基础镜像 FROM postgres:12# 环境变量&#xff0c;配置数据库用户名和密码 ENV POSTGRES_USER postgres ENV POSTGRES_PASSWORD 123456# 将初始化数据库的脚本复制到docker…

2024骨传导耳机品牌排行前五名汇总,揭晓年度最强王者骨传导机型!

骨传导耳机自问世以来&#xff0c;便迅速在蓝牙耳机市场中崭露头角&#xff0c;并且凭借特殊的传声方式和特健康的佩戴方式深得消费者的喜爱。然而&#xff0c;随着骨传导耳机逐渐热门&#xff0c;市场中品牌越来越多&#xff0c;也逐渐出现了一些劣质品牌&#xff0c;这些品牌…

小朋友分糖果-第13届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第79讲。 小朋友分糖果&…