Netty通信中的粘包半包问题(三)

之前我们介绍了用特殊分隔符来分割每个报文,但是如果传输的数据中恰好有个特殊分隔符,它将会被拆分成多个,于是,为了进一步避免这个问题,还有一种解决方案是在两端的channelPipeline中用一个固定长度来区分,这样也可以解决粘包半包的问题

1.Server

package splicing.fixed;import constant.Constant;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.FixedLengthFrameDecoder;import java.net.InetSocketAddress;public class FixedLengthEchoServer {public static final String RESPONSE = "Welcome to Netty";public static void main(String[] args) throws InterruptedException {FixedLengthEchoServer fixedLengthEchoServer = new FixedLengthEchoServer();System.out.println("服务器即将启动");fixedLengthEchoServer.start();}public void start() throws InterruptedException {FixedLengthServerHandler serverHandler = new FixedLengthServerHandler();EventLoopGroup group = new NioEventLoopGroup();// 线程组try {// 服务端启动必须ServerBootstrap b = new ServerBootstrap();b.group(group)// 将线程组传入.channel(NioServerSocketChannel.class) // 指定使用NIO进行网络传输.localAddress(new InetSocketAddress(Constant.DEFAULT_PORT)) // 指定服务器监听端口// 服务端每接收到一个连接请求,就会新启一个Socket通信,也就是channel// 所以下面这段代码的作用就是为这个子channel增加handler.childHandler(new ChannelInitializerImp());// 异步绑定到服务器,sync()会阻塞直到完成ChannelFuture f = b.bind().sync();System.out.println("服务器启动完成,等待客户端的连接和数据.....");// 阻塞直到服务器的channel关闭f.channel().closeFuture().sync();} finally {group.shutdownGracefully().sync();}}private static class ChannelInitializerImp extends ChannelInitializer<Channel> {@Overrideprotected void initChannel(Channel ch) throws Exception {ch.pipeline().addLast(new FixedLengthFrameDecoder(FixedLengthEchoClient.REQUEST.length()));ch.pipeline().addLast(new FixedLengthServerHandler());}}
}
package splicing.fixed;import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;import java.util.concurrent.atomic.AtomicInteger;public class FixedLengthServerHandler extends ChannelInboundHandlerAdapter {private AtomicInteger counter = new AtomicInteger(0);@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf in = (ByteBuf) msg;String request = in.toString(CharsetUtil.UTF_8);System.out.println("Server Accept[" + request +" ] and the counter is :" + counter.incrementAndGet());ctx.writeAndFlush(Unpooled.copiedBuffer(FixedLengthEchoServer.RESPONSE.getBytes()));
//        super.channelRead(ctx, msg);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();
//        super.exceptionCaught(ctx, cause);}
}

2.Client

package splicing.fixed;import constant.Constant;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.FixedLengthFrameDecoder;import java.net.InetSocketAddress;public class FixedLengthEchoClient {public static final String REQUEST = "Mark,zhuge,zhouyu,fox,loulan";private final String host;public FixedLengthEchoClient(String host) {this.host = host;}public void start() throws InterruptedException {EventLoopGroup group = new NioEventLoopGroup();try {// 客户端启动必须Bootstrap b = new Bootstrap();b.group(group)// 将线程组传入.channel(NioSocketChannel.class) // 指定使用NIO进行网络传输.remoteAddress(new InetSocketAddress(host, Constant.DEFAULT_PORT)).handler(new ChannelInitializerImp());ChannelFuture f = b.connect().sync();System.out.println("已连接到服务器....");f.channel().closeFuture().sync();} finally {group.shutdownGracefully().sync();}}private static class ChannelInitializerImp extends ChannelInitializer<Channel> {@Overrideprotected void initChannel(Channel ch) throws Exception {ch.pipeline().addLast(new FixedLengthFrameDecoder(FixedLengthEchoServer.RESPONSE.length()));ch.pipeline().addLast(new FixedLengthClientHandler());}}public static void main(String[] args) throws InterruptedException {new FixedLengthEchoClient(Constant.DEFAULT_SERVER_IP).start();}
}
package splicing.fixed;import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;import java.util.concurrent.atomic.AtomicInteger;public class FixedLengthClientHandler extends SimpleChannelInboundHandler<ByteBuf> {private AtomicInteger counter = new AtomicInteger(0);@Overrideprotected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {System.out.println("client Accept [" + msg.toString(CharsetUtil.UTF_8)+ "] and the counter is :" + counter.incrementAndGet());}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {ByteBuf msg = null;for (int i = 0; i < 100; i++) {msg = Unpooled.buffer(FixedLengthEchoClient.REQUEST.length());msg.writeBytes(FixedLengthEchoClient.REQUEST.getBytes());ctx.writeAndFlush(msg);}
//        super.channelActive(ctx);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();
//        super.exceptionCaught(ctx, cause);}
}

3.结果展示

在这里插入图片描述
在这里插入图片描述

这种方案的限制在于要提前直到客户端和服务端要发送的报文,并且这个长度是固定的,不能变,如果变了,还是会产生粘包半包的问题,那么有的人可能会想,有没有更好的解决方案,别着急,下一期我们接着分析

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

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

相关文章

K8s(一)Pod资源——Pod介绍、创建Pod、Pod简单资源配额

目录 Pod概述 pod网络 pod存储 pod和容器对比 创建pod的方式 pod运行方式分类 Pod的创建 Pod的创建过程 通过kubectl run来创建pod 通过yaml文件创建&#xff0c;yaml文件简单写法 Pod简单操作 Pod的标签labels Pod的资源配额resource 测试 Pod概述 Kubernetes …

贪心算法-活动安排-最详细注释解析

贪心算法-活动安排-最详细注释解析 题目&#xff1a; 学校在最近几天有n个活动&#xff0c;这些活动都需要使用学校的大礼堂&#xff0c;在同一时间&#xff0c;礼堂只能被一个活动使用。由于有些活动时间上有冲突&#xff0c;学校办公室人员只好让一些活动放弃使用礼堂而使用…

Arm Generic Interrupt Controller v3 and v4(GICv3v4)学习(一)

提示 该博客主要为个人学习&#xff0c;通过阅读官网手册整理而来&#xff08;个人觉得阅读官网的英文文档非常有助于理解各个IP特性&#xff09;。若有不对之处请参考参考文档&#xff0c;以官网参考文档为准。 Arm Generic Interrupt Controller v3 and v4学习一共分为三章&…

Revealing the Dark Secrets of MIM

论文名称&#xff1a; Revealing the Dark Secrets of Masked Image Modeling 发表时间&#xff1a;CVPR2022 作者及组织&#xff1a;Zhenda Xie, Zigang Geng, Hu Han等&#xff0c;来自清华&#xff0c;中科院&#xff0c;微软亚洲研究院。 前言 本文尝试探讨MIM为何有效的原…

JavaScript 学习笔记(Day5)

「写在前面」 本文为 b 站黑马程序员 pink 老师 JavaScript 教程的学习笔记。本着自己学习、分享他人的态度&#xff0c;分享学习笔记&#xff0c;希望能对大家有所帮助。推荐先按顺序阅读往期内容&#xff1a; 1. JavaScript 学习笔记&#xff08;Day1&#xff09; 2. JavaSc…

数据结构奇妙旅程之二叉树初阶

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

IDEA无法解析jdk自带的类的解决办法

1.问题 IDEA在有些时候&#xff0c;会出现这个错误&#xff0c;就是jdk自带的java类找不到而报错。 例如下面的就是Object找不到&#xff0c;我们知道jdk自带的类是不用import包的&#xff0c;这里报错了&#xff0c;IDEA会提示你去导入类&#xff0c;其实这个提示也不是真正…

Ubuntu 22.04 基础环境搭建

这是Ubuntu软件安装系列的第一篇&#xff0c;我们来聊聊基础环境搭建。 这个专栏主要讲一些常见服务端软件的安装和配置&#xff0c;当然也包括对软件架构和作用的分析&#xff0c;以及使用的场景的介绍。 注意我们这里使用的Ubuntu的版本是22.04&#xff0c;基本上大厂的云服…

CentOS安装maxwell

CentOs安装maxwell 一、简介二、准备工作三、安装1、下载安装包2、解压3、编写配置文件4、启动maxwell5、验证6、停止maxwell 四、说明1、更新数据2、插入数据3、删除数据 五、遇到问题 一、简介 maxwell是由美国Zendesk公司开源&#xff0c;它通过读取mysql的binlog日志&#…

vscode mysql cmake windows 常见问题和推荐文章

1.在windows中安装mingw64和cmake&#xff08;可查一下网上的安装教程&#xff09;&#xff0c;配置环境变量 2.在vscode中用CMake构建项目的时候&#xff0c;可能会出现这样的问题:“The C compiler identification is unknownn...”,可参考这篇博客 在windows下使用Vscode用…

面试题之ElasticSearch

面试题之ElasticSearch 1.es的基础知识2. es的集群、节点、分片、副本分片的定义&#xff1f;3. es为什么快&#xff1f;4. 倒排索引的原理是什么&#xff1f;5. es的segment是什么&#xff1f;6. es的分段存储和分段索引的概念及区别&#xff1f;7. 索引相关的问题&#xff1f…

服务器感染了.DevicData-P-XXXXXXXX勒索病毒,如何确保数据文件完整恢复?

引言&#xff1a; 在当今数字化时代&#xff0c;勒索病毒已成为网络安全威胁的一个严峻问题。其中&#xff0c;.DevicData-P-XXXXXXXX 勒索病毒以其恶意加密文件的手段引起了广泛关注。本文将介绍该病毒的特点、数据恢复方法以及如何预防遭受其攻击。 如不幸感染这个勒索病毒&…

【Java数据结构】03-二叉树,树和森林

4 二叉树、树和森林 重点章节&#xff0c;在选择&#xff0c;填空&#xff0c;综合中都有考察到。 4.1 掌握二叉树、树和森林的定义以及它们之间的异同点 1. 二叉树&#xff08;Binary Tree&#xff09; 定义&#xff1a; 二叉树是一种特殊的树结构&#xff0c;其中每个节点…

Python(wordcloud):根据词频信息(xlsx、csv文件)绘制词云图

一、前言 本文将介绍如何用python根据词频信息&#xff08;xlsx、csv文件&#xff09;绘制词云图&#xff0c;除了绘制常规形状的词云图&#xff08;比如长方形&#xff09;&#xff0c;还可以指定词云图的形状。 二、安装并引入相关的库 1、安装相关的库 pip install jieb…

MinIO上传

简介 MinIO是一个开源的对象存储服务器&#xff0c;兼容Amazon S3 API。它提供了可扩展、高性能和高可用性的存储解决方案&#xff0c;适用于大规模数据存储和分发。 MinIO的设计目标是简单易用、轻量级和高度可定制。它可以在企业内部部署&#xff0c;也可以在公有云上使用。…

深度学习笔记(八)——构建网络的常用辅助增强方法:数据增强扩充、断点续训、可视化和部署预测

文中程序以Tensorflow-2.6.0为例 部分概念包含笔者个人理解&#xff0c;如有遗漏或错误&#xff0c;欢迎评论或私信指正。 截图和程序部分引用自北京大学机器学习公开课 要构建一个完善可用的神经网络&#xff0c;除了设计网络结构以外&#xff0c;还需要添加一些辅助代码来增强…

【Macos系统】安装VOSviewer及使用VOSviewer教程!!以ESN网络的研究进行案例分析

【Macos系统】安装VOSviewer及使用VOSviewer教程 以ESN网络的研究进行案例分析 本文介绍如何安装和使用VOSviewer软件&#xff0c;并以ESN&#xff08;Echo State Network&#xff09;网络的研究为案例进行分析。利用VOSviewer对相关文献进行可视化分析&#xff0c;并深入了解…

Linux之引导和服务篇

系统引导是操作系统运行的开始&#xff0c;在用户能够正常登录之前&#xff0c;Linux的引导过程完成了一系列的初始化任务&#xff0c;并加载必要的程序和命令终端&#xff0c;为用户登录做好准备。 一. 引导过程 开机自检--->MBR引导--->GRUB菜单--->加载Linux内核-…

商汤书生大模型一次可读 30 万汉字;2023 年 Shopee Live 超100万马来人注册;2023年中国出生人口902万人;

今日精选 • 商汤“书生・浦语”2.0 大语言模型开源&#xff1a;200K 上下文&#xff0c;一次可读 30 万汉字• 2023年中国出生人口902万人• 2023 年 Shopee Live 有超 100 万马来人注册并观看直播 投融资 • Airbnb 2 亿美元收购人工智能初创公司 Gameplanner.AI• 哥伦比…

【JavaEEj进阶】 Spring实现留言板

文章目录 &#x1f38d;预期结果&#x1f340;前端代码&#x1f384;约定前后端交互接⼝&#x1f6a9;需求分析&#x1f6a9;接⼝定义 &#x1f333;实现服务器端代码&#x1f6a9;lombok &#x1f332;服务器代码实现&#x1f334;运⾏测试 &#x1f38d;预期结果 可以发布并…