客户端自定义回调函数:
package com.niuh.netty.base;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;public class NettyClientHandler extends ChannelInboundHandlerAdapter { /** * 当客户端连接服务器完成就会触发该方法 * * @param ctx * @throws Exception */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { ByteBuf buf = Unpooled.copiedBuffer("HelloServer".getBytes(CharsetUtil.UTF_8)); ctx.writeAndFlush(buf); } //当通道有读取事件时会触发,即服务端发送数据给客户端 @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; System.out.println("收到服务端的消息:" + buf.toString(CharsetUtil.UTF_8)); System.out.println("服务端的地址: " + ctx.channel().remoteAddress()); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); }}
与NettyServerHandler类似,其中的channelActive()方法是当客户端与服务器连接完成时候就会执行的方法 。
看完代码,我们发现Netty架的目标就是让你的业务逻辑从网络基础应用编码中分离出来,让你可以专 注业务的开发,而不需写一大堆类似NIO的网络处理操作 。ByteBuf 理解从结构上来说,ByteBuf 由一串字节数组构成 。数组中每个字节用来存放信息 。
ByteBuf 提供了两个索引,一个用于读取数据,一个用于写入数据 。这两个索引通过在字节数组中移动,来定位需要读或者写信息的位置 。
- 当从 ByteBuf 读取时,它的 readerIndex(读索引)将会根据读取的字节数递增 。
- 同样,当写 ByteBuf 时,它的 writerIndex 也会根据写入的字节数进行递增 。
文章插图
ByteBuf.png
需要注意的是极限的情况是 readerIndex 刚好读到了 writerIndex 写入的地方 。如果 readerIndex 超过了 writerIndex 的时候,Netty 会抛出 IndexOutOf-BoundsException 异常 。
示例代码
package com.niuh.netty.base;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.util.CharsetUtil;public class NettyByteBuf { public static void main(String[] args) { // 创建byteBuf对象,该对象内部包含一个字节数组byte[10] // 通过readerindex和writerIndex和capacity,将buffer分成三个区域 // 已经读取的区域:[0,readerindex) // 可读取的区域:[readerindex,writerIndex) // 可写的区域: [writerIndex,capacity) ByteBuf byteBuf = Unpooled.buffer(10); System.out.println("byteBuf=" + byteBuf); for (int i = 0; i < 8; i++) { byteBuf.writeByte(i); } System.out.println("byteBuf=" + byteBuf); for (int i = 0; i < 5; i++) { System.out.println(byteBuf.getByte(i)); } System.out.println("byteBuf=" + byteBuf); for (int i = 0; i < 5; i++) { System.out.println(byteBuf.readByte()); } System.out.println("byteBuf=" + byteBuf); //用Unpooled工具类创建ByteBuf ByteBuf byteBuf2 = Unpooled.copiedBuffer("hello,zhangsan!", CharsetUtil.UTF_8); //使用相关的方法 if (byteBuf2.hasArray()) { byte[] content = byteBuf2.array(); //将 content 转成字符串 System.out.println(new String(content, CharsetUtil.UTF_8)); System.out.println("byteBuf=" + byteBuf2); System.out.println(byteBuf2.readerIndex()); // 0 System.out.println(byteBuf2.writerIndex()); // 12 System.out.println(byteBuf2.capacity()); // 36 System.out.println(byteBuf2.getByte(0)); // 获取数组0这个位置的字符h的ascii码,h=104 int len = byteBuf2.readableBytes(); //可读的字节数 12 System.out.println("len=" + len); //使用for取出各个字节 for (int i = 0; i < len; i++) { System.out.println((char) byteBuf2.getByte(i)); } //范围读取 System.out.println(byteBuf2.getCharSequence(0, 6, CharsetUtil.UTF_8)); System.out.println(byteBuf2.getCharSequence(6, 6, CharsetUtil.UTF_8)); } }}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 浅谈 Netty三种 I/O 模式和Reactor 编程模式
- 猫咪可以经常换猫砂吗 猫咪猫砂多久彻底换一次
- 如何彻底清理干净电脑里的垃圾?
- 用Netty实现Http服务器
- 一文搞懂分类算法中常用的评估指标
- 基于netty手写Tomcat
- 看了两天HashMap源码,终于把红黑树插入平衡规则搞懂了
- 三分钟搞懂SQL的Case函数
- 蒙古后来为什么不进攻明朝了 为什么明朝没有彻底消灭蒙古
- spring注入你真搞懂了吗?不会一直都是这样错误理解吧?