Netty中定長解碼器的使用
阿新 • • 發佈:2018-02-12
ble 解碼器 erb cau option bootstra cef 成功 ios [toc]
Netty中定長解碼器的使用
有了前面的基礎,定長解碼器的使用相對就比較簡單了,所以這裏只使用服務端的代碼,測試時,用telnet作為客戶客戶端,數據只作單向的發送,即從客戶端到服務端。
服務端
EchoServer.java
package cn.xpleaf.netty02; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.FixedLengthFrameDecoder; import io.netty.handler.codec.string.StringDecoder; public class EchoServer { public void bind(int port) throws Exception { // 配置服務端的NIO線程組 EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 1024) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { // 添加定長分隔符解碼器到pipeline中,長度設置為20 ch.pipeline().addLast(new FixedLengthFrameDecoder(20)); // 添加StringDecoder解碼器,將ByteBuf解碼成字符串對象 ch.pipeline().addLast(new StringDecoder()); // 添加業務處理handler ch.pipeline().addLast(new EchoServerHandler()); } }); // 綁定端口,同步等待成功 ChannelFuture f = b.bind(port).sync(); // 等待服務端監聽端口關閉 f.channel().closeFuture().sync(); } finally { // 優雅退出,釋放線程池資源 bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; if(args != null && args.length > 0) { try { port = Integer.valueOf(port); } catch (NumberFormatException e) { // TODO: handle exception } } new EchoServer().bind(port); } }
EchoServerHandler.java
package cn.xpleaf.netty02; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; public class EchoServerHandler extends ChannelInboundHandlerAdapter { private int counter = 0; @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { String body = (String) msg; System.out.println("Receive client : [" + body + "]"); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // 發生異常,關閉鏈路 ctx.close(); } }
測試
啟動服務端,在telnet客戶端中輸入相應字符串:
yeyonghao@yeyonghaodeMacBook-Pro:~$ telnet localhost 8080
Trying ::1...
Connected to localhost.
Escape character is ‘^]‘.
Ye Yonghao welcome to Beijing
此時查看服務端的輸出:
Receive client : [Ye Yonghao welcome t]
可以看到中括號時字符數剛好是20個,因為在pipeline中設置定長解碼器時,設置的長度就是20。
可以嘗試再發送消息:
yeyonghao@yeyonghaodeMacBook-Pro:~$ telnet localhost 8080 Trying ::1... Connected to localhost. Escape character is ‘^]‘. Ye Yonghao welcome to Beijing I love you so much!
再查看服務端的輸出:
Receive client : [Ye Yonghao welcome t]
Receive client : [o Beijing
I love yo]
可以看到服務端把上一次的消息作為這次消息的開始,包括換行符,這說明定長解碼器確實是有效果了。
Netty中定長解碼器的使用