netty 客户端断开 异常处理_netty案例,netty4.1基础入门篇八《NettyClient半包粘包处理》发数据方式》...

小傅哥 | https://bugstack.cn 沉淀、分享、成长,让自己和他人都能有所收获。专注于原创专题案例编写,目前已完成的专题有;Netty4.x实战专题案例、用Java实现JVM、基于JavaAgent的全链路监控、手写RPC框架、架构设计专题案例、源码分析等。你用剑 、我用刀 ,好的代码都很烧,望你不吝出招!

一、前言介绍

Netty开发中,客户端与服务端需要保持同样的;半包粘包处理,编码解码处理、收发数据方式,这样才能保证数据通信正常。在前面NettyServer的章节中我们也同样处理了;半包粘包、编码解码等,为此在本章节我们可以把这些知识模块开发到NettyClient中。本章节涉及到的知识点有;LineBasedFrameDecoder、StringDecoder、StringEncoder、ChannelInboundHandlerAdapter等。

二、开发环境

  1. jdk1.8【jdk1.7以下只能部分支持netty】
  2. Netty4.1.36.Final【netty3.x 4.x 5每次的变化较大,接口类名也随着变化】
  3. telnet 测试【可以现在你的win7机器上测试这个命令,用于链接到服务端的测试命令】

三、代码示例

itstack-demo-netty-1-08
└── src├── main│   └── java│       └── org.itstack.demo.netty.client│           ├── MyChannelInitializer.java│           ├── MyClientHandler.java│           └── NettyClient.java└── test└── java└── org.itstack.demo.netty.test└── ApiTest.java
MyChannelInitializer.java
/*** 虫洞栈:https://bugstack.cn* 公众号:bugstack虫洞栈  {获取学习源码}* Create by fuzhengwei on 2019*/
public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel channel) throws Exception {// 基于换行符号channel.pipeline().addLast(new LineBasedFrameDecoder(1024));// 解码转String,注意调整自己的编码格式GBK、UTF-8channel.pipeline().addLast(new StringDecoder(Charset.forName("GBK")));// 解码转String,注意调整自己的编码格式GBK、UTF-8channel.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));// 在管道中添加我们自己的接收数据实现方法channel.pipeline().addLast(new MyClientHandler());}}
MyClientHandler.java
/*** 虫洞栈:https://bugstack.cn* 公众号:bugstack虫洞栈  {获取学习源码}* Create by fuzhengwei on 2019*/
public class MyClientHandler extends ChannelInboundHandlerAdapter {/*** 当客户端主动链接服务端的链接后,这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据*/@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {SocketChannel channel = (SocketChannel) ctx.channel();System.out.println("链接报告开始");System.out.println("链接报告信息:本客户端链接到服务端。channelId:" + channel.id());System.out.println("链接报告IP:" + channel.localAddress().getHostString());System.out.println("链接报告Port:" + channel.localAddress().getPort());System.out.println("链接报告完毕");//通知客户端链接建立成功String str = "通知服务端链接建立成功" + " " + new Date() + " " + channel.localAddress().getHostString() + "rn";ctx.writeAndFlush(str);}/*** 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据*/@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {System.out.println("断开链接" + ctx.channel().localAddress().toString());}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {//接收msg消息{与上一章节相比,此处已经不需要自己进行解码}System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " 接收到消息:" + msg);//通知客户端链消息发送成功String str = "客户端收到:" + new Date() + " " + msg + "rn";ctx.writeAndFlush(str);}/*** 抓住异常,当发生异常的时候,可以做一些相应的处理,比如打印日志、关闭链接*/@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx.close();System.out.println("异常信息:rn" + cause.getMessage());}}
NettyClient.java
/*** 虫洞栈:https://bugstack.cn* 公众号:bugstack虫洞栈  {获取学习源码}* Create by fuzhengwei on 2019*/
public class NettyClient {public static void main(String[] args) {new NettyClient().connect("127.0.0.1", 7397);}private void connect(String inetHost, int inetPort) {EventLoopGroup workerGroup = new NioEventLoopGroup();try {Bootstrap b = new Bootstrap();b.group(workerGroup);b.channel(NioSocketChannel.class);b.option(ChannelOption.AUTO_READ, true);b.handler(new MyChannelInitializer());ChannelFuture f = b.connect(inetHost, inetPort).sync();System.out.println("itstack-demo-netty client start done. {关注公众号:bugstack虫洞栈,获取源码}");f.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {workerGroup.shutdownGracefully();}}}

四、测试结果

启动模拟器NetAssist 设置TCP Server

9f98daa9ad52a8d0151372f36b732d5d.png
启动客户端NettyClient

8243cede36f9b88df068cd01b6c5bdb1.png
执行结果
/*** 虫洞栈:https://bugstack.cn* 公众号:bugstack虫洞栈  {获取学习源码}* Create by fuzhengwei on 2019*/
public class NettyClient {public static void main(String[] args) {new NettyClient().connect("127.0.0.1", 7397);}private void connect(String inetHost, int inetPort) {EventLoopGroup workerGroup = new NioEventLoopGroup();try {Bootstrap b = new Bootstrap();b.group(workerGroup);b.channel(NioSocketChannel.class);b.option(ChannelOption.AUTO_READ, true);b.handler(new MyChannelInitializer());ChannelFuture f = b.connect(inetHost, inetPort).sync();System.out.println("itstack-demo-netty client start done. {关注公众号:bugstack虫洞栈,获取源码}");f.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {workerGroup.shutdownGracefully();}}}

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

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

相关文章

Java Windows注销用户,中止Windows从Java注销

EDIT2对于那些跟随讨论的人&#xff0c;我留下了我的第一个答案&#xff0c;但似乎他们没有工作。首先找到我的真正解决方案好吧&#xff0c;所以我认为这实际上有效&#xff0c;但它并不完全可以接受&#xff0c;因为它使用了受限制的API部分(但它自Java 1.3以来就存在并且仍然…

python generator_Python Generator漫谈

作为一个Python初学者, Python的格式化语法让众多编程小白追捧, 它的语法糖让代码变得简洁易读&#xff0c;它的庞大开源库让它在各个领域都能发挥作用. 但我时常感受到这个门槛极低的语言远没有表面上看起来易懂易用. 在Python的学习之路上, 我也时常迷茫于自己是否真正掌握了…

php5.5 连接数据库,php5.5 session_set_save_handler 连接数据库问题

好久前忘了在什么地方抄来的&#xff0c;一直好用&#xff0c;但是升级到PHP5.5就不好用了 出现警告服务器无法修改PHP.ini 只好自己试着用mysqli写 但是一直写不出来 请高手指教&#xff01;&#xff01;谢谢回复讨论(解决方案)把 mysql_ 都改成 mysqli_>把 mysql_ 都改成 …

python获取屏幕文字_详解:四种方法教你对Python获取屏幕截图(PyQt , pyautogui)...

前言&#xff1a;今天为大家带来的内容是详解&#xff1a;四种方法教你对Python获取屏幕截图(PyQt , pyautogui)本文具有不错的参考意义&#xff0c;希望能够帮助到大家&#xff01;Python获取电脑截图有多种方式&#xff0c;具体如下&#xff1a;1. PIL中的ImageGrab模块2. wi…

支付宝php异步回调,支付宝支付成功之后异步回调处理

/*** alipay_notify.php.* User: lvfk* Date: 2017/10/26 0026* Time: 13:48* Desc: 支付宝支付成功异步通知*/include_once (__DIR__./../alipay-sdk-PHP-20171023143822/AopSdk.php);//验证签名$aop new \AopClient();$aop->alipayrsaPublicKey \Comm\Pay\Alipay::ALIPA…

python frame如何置顶_Python tkinter frame父窗口小部件排列列

我把滚动条放在一个框架里&#xff0c;框架放在一个小部件里。这个框架上面有一个标签。上面的标签有三列。带有滚动条的框架有三列。我无法让框架内和框架上方的三根柱子对齐。在如果您能帮我排好纵队&#xff0c;我们将不胜感激。谢谢。在以下是MWE&#xff1a;import tkinte…

MySQL和mq一致性,Mysql与Redis一致性问题

缓存一致性产生背景如果每次频繁的访问数据库的时候&#xff0c;虽然查询底层使用B树索引 但还会做磁盘的IO操作&#xff0c;可能会对数据库的压力非常大。所以为了能够减轻数据库的访问压力&#xff0c;会使用一些缓存实现减轻数据库的压力。比如 Redis、es、ehcache、oscache…

python boolean_Python成为专业人士笔记-Boolean 布尔操作符研究

专业人士笔记”系列目录&#xff1a;创帆云&#xff1a;Python成为专业人士笔记--强烈建议收藏&#xff01;每日持续更新&#xff01;​zhuanlan.zhihu.com‘and’ 和 ‘or’ 并不一定返回一个布尔值当使用or时&#xff0c;如果为真&#xff0c;它将返回表达式中的第一个值&…

python八大选择排序_python之八大排序方法

排序方法 平均情况 最好情况 最坏情况 辅助空间 稳定性冒泡排序 O(n^2) O(n) O(n^2) O(1) 稳定选择排序 O(n^2) O(n^2) O(n^2) O(1) 不稳定插入…

int arr 13 java,java学习13 - 数组的定义、操作、异常、二维数组

续java学习12&#xff1a;1、数组,引用类型变量&#xff0c;保存数据实际是保存的数组的首地址2、定义数组容器三要素&#xff0c;数据类型&#xff0c;大小(长度)&#xff0c;数组名3、数组的定义公式一&#xff1a;数据类型[] 数组名 new 数据类型[元素个数或数组长度]4、数…

clustalw序列比对_序列比对(二)

Homology is the central concept for all of biology.——David Wake. Science, 1994前言正如前面引用的这句话&#xff0c;同源性是生物学中的核心问题。研究序列的同源性问题&#xff0c;就要用到序列比对的工具&#xff0c;上一篇笔记简单介绍了序列比对的原理&#xff0c;…

java js引擎,Java8 Nashorn JavaScript引擎

使用Java8&#xff0c;Nashorn大大提高了JavaScript 引擎引入&#xff0c;以取代现有的Nashorn Java脚本引擎。Nashorn提供2至10倍更好的性能&#xff0c;因为它直接编译代码在存储器&#xff0c;并传递到字节码JVM.Nashorn使用invokedynamics函数&#xff0c;在Java7引入以提高…

pr渲染程序选哪个_PR的bug你遇到过几个?

哈喽 大家好呀 我是K同学&#xff01;对于Pr的用户来讲&#xff0c;Pr有很多BUG让人很奔溃&#xff0c;不仅Pr奔溃了&#xff0c;人都奔溃了作为Pr的老用户&#xff0c;今天我就来盘点下&#xff0c;我遇到过Pr的变态BUG第一个Pr不支持微软输出法这是我使用Pr遇到的第一个BUG&a…

java model 中文乱码,java传值乱码解决方法

在做JavaWeb时&#xff0c;总是时不时的会遇到中文传值乱码问题&#xff0c;在你把所有”ISO-8859-1”改成“UTF-8”发现还是没什么用。于是我就找到了一个百试百灵的方法(至少目前我是)&#xff0c;就是强行转换成“UTF-8”编码。看代码&#xff1a;RequestMapping("/suc…

检查一列数据的重复项 vba_提取重复值,但字典不是重点。

本例的问题描述&#xff1a;1&#xff1a;源数据与提取的结果在同一个工作表里面&#xff1b;2&#xff1a;提取K、M、O、Q列里面不重复的数据(注意&#xff0c;数据列里面有空白的行)&#xff1b;3&#xff1a;把提取出来的结果放在A2单元格的下方&#xff0c;不能有空白行&am…

swiper怎么让不会回弹,为什么我的滚动条拉上拉下都会回弹呢?

其它都是正常的&#xff0c;就是拉上去拉下来自己又回弹回去了&#xff0c;拉不到最底部也拉不到最顶部&#xff0c;拉来拉去都会是这样的category/index.vueimport CategoryHeader from "./header";import CategoryTab from "./tab";import CategoryConte…

异构服务器 微服务_Spring Cloud Alibaba Sidecar 多语言微服务异构

Spring Cloud Alibaba Sidecar 介绍自 Spring Cloud Alibaba 2.1.1 版本后增加了 spring-cloud-alibaba-sidecar 模块作为作为一个代理的服务来间接性的让其他语言可以使用spring cloud alibaba等相关组件。通过与网关的来进行路由的映射&#xff0c;从而可以做到服务的获取&am…

采用的php cms分校站点 打开特别慢,phpcms v9 打开网站特别慢 增加数据库缓存方法...

SET GLOBAL QUERY_CACHE_SIZE80000000;设置好查询缓存的大小就行了。比如设置个20MB.SET GLOBAL QUERY_CACHE_SIZE20000000;mysql会将查询SQL和结果集存到缓存中&#xff0c;等下次遇到相同的SQL语句时&#xff0c;结果集从缓存中读取。1.设置缓存大小时&#xff0c;至少给它40…

python3 console input_Python3 tkinter基础 Button command 单击按钮 在console中打印文本

Python : 3.7.0OS : Ubuntu 18.04.1 LTSIDE : PyCharm 2018.2.4Conda : 4.5.11typesetting : Markdowncode"""Author : 行初心Date : 18-10-1Blog : www.cnblogs.com/xingchuxinGitee : gitee.com/zhichengjiu"""import tkinter as tk# 面向对象…

matlab教程点语言,编程语言 / Matlab教程_电脑教程学习网( 5 )

逐次超松弛方法(SOR方法)求解方程组日期&#xff1a;2014-09-26 21:03:34点击&#xff1a;370好评&#xff1a;0#includeiostream.h//逐次超松弛方法(SOR方法)求解方程组 #includemath.h #includeiomanip.h #define n 3 void main() { double A[n][n]{{5,2,1},{-1,4,2},{2,-3,1…