日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Netty 框架学习(二):DelimiterBasedFrameDecoder和FixedLengthFrameDecoder

發布時間:2025/1/21 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Netty 框架学习(二):DelimiterBasedFrameDecoder和FixedLengthFrameDecoder 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 一、DelimiterBasedFrameDecoder
      • 服務端
        • 1、EchoServer
        • 2、EchoServerChannelHandler
        • 3、EchoServerHandler
      • 客戶端
        • 1、EchoClient
        • 2、EchoClientChannelHandler
        • 3、EchoClientHandler
    • 二、FixedLengthFrameDecoder

TCP以流的方式進行數據傳輸,上層應用協議為了對消息進行區分,一般采用如下4種方式:

1.消息長度固定,累計讀取到消息長度總和為定長Len的報文之后即認為是讀取到了一個完整的消息。計數器歸位,重新讀取。
2. 將回車換行符作為消息結束符。
3. 將特殊的分隔符作為消息分隔符,回車換行符是他的一種。
4. 通過在消息頭定義長度字段來標識消息總長度。

LineBasedframeDecoder屬于第二種,今天我們要說的DelimiterBasedFrameDecoder和FixedLengthFrameDecoder屬于第三種和第一種。DelimiterBasedFrameDecoder用來解決以特殊符號作為消息結束符的粘包問題,FixedLengthFrameDecoder用來解決定長消息的粘包問題。

一、DelimiterBasedFrameDecoder

服務端

1、EchoServer

/*** @author shuliangzhao* @Title: EchoServer* @ProjectName design-parent* @Description: TODO* @date 2019/8/21 20:53*/ public class EchoServer {public void start(int port) {EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workGroup = new NioEventLoopGroup();ServerBootstrap serverBootstrap = new ServerBootstrap().group(bossGroup,workGroup).channel(NioServerSocketChannel.class).childHandler(new EchoServerChannelHandler());try {ChannelFuture future = serverBootstrap.bind(port).sync();future.channel().closeFuture().sync();} catch (Exception e) {e.printStackTrace();} finally {bossGroup.shutdownGracefully();workGroup.shutdownGracefully();}}public static void main(String[] args) {new EchoServer().start(8080);} }

2、EchoServerChannelHandler

/*** @author shuliangzhao* @Title: EchoServerChannelHandler* @ProjectName design-parent* @Description: TODO* @date 2019/8/21 20:59*/ public class EchoServerChannelHandler extends ChannelInitializer<SocketChannel> {protected void initChannel(SocketChannel socketChannel) throws Exception {ChannelPipeline pipeline = socketChannel.pipeline();ByteBuf byteBuf = Unpooled.copiedBuffer("\t".getBytes());pipeline.addLast(new DelimiterBasedFrameDecoder(1024,byteBuf));pipeline.addLast(new StringDecoder());pipeline.addLast(new StringEncoder());pipeline.addLast(new EchoServerHandler());} }

3、EchoServerHandler

public class EchoServerHandler extends ChannelInboundHandlerAdapter {private int counter;@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {String body = (String) msg;System.out.println("server reciver oder:" + body + ";this counter is:" + ++counter);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {super.exceptionCaught(ctx, cause);} }

客戶端

1、EchoClient

public class EchoClient {public void start(String address,int port) {EventLoopGroup group = new NioEventLoopGroup();Bootstrap bootstrap = new Bootstrap();bootstrap.group(group).channel(NioSocketChannel.class).handler(new EchoClientChannelHandler());try {ChannelFuture future = bootstrap.connect(address,port).sync();future.channel().closeFuture().sync();} catch (Exception e) {e.printStackTrace();}finally {group.shutdownGracefully();}}public static void main(String[] args) {new EchoClient().start("127.0.0.1",8080);} }

2、EchoClientChannelHandler

public class EchoClientChannelHandler extends ChannelInitializer<SocketChannel> {protected void initChannel(SocketChannel socketChannel) throws Exception {ChannelPipeline pipeline = socketChannel.pipeline();/** 這個地方的 必須和服務端對應上。否則無法正常解碼和編碼*/ByteBuf delimiter = Unpooled.copiedBuffer("\t".getBytes());pipeline.addLast(new DelimiterBasedFrameDecoder(1024,delimiter));pipeline.addLast( new StringDecoder());pipeline.addLast( new StringEncoder());// 客戶端的邏輯pipeline.addLast( new EchoClientHandler());} }

3、EchoClientHandler

public class EchoClientHandler extends ChannelInboundHandlerAdapter {private byte[] req;private int counter;public EchoClientHandler() {req = ("There are moments in life when you miss\t" +"someone so much that you just want to pick\t" +"them from your dreams and hug them for real!\t" +"Dream what you want to dream;go where you want\t" +"to go be what you want to be,because you have only\t" +"one life and one chance to do all the things you want to do\t").getBytes();}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {ByteBuf message = Unpooled.buffer(req.length);message.writeBytes(req);ctx.writeAndFlush(message);}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {String body = (String) msg;System.out.println("client reciver is :" + body + "this is counter:" + ++counter);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx.close();} }

運行結果:

這里我們添加DelimiterBasedFrameDecoder解碼器并且手動指定消息分隔符為:”\t”。我們可以看一下DelimiterBasedFrameDecoder的構造方法:

public DelimiterBasedFrameDecoder(int maxFrameLength, boolean stripDelimiter, ByteBuf delimiter) {this(maxFrameLength, stripDelimiter, true, delimiter); }

maxFrameLength:解碼的幀的最大長度

stripDelimiter:解碼時是否去掉分隔符

failFast:為true,當frame長度超過maxFrameLength時立即報TooLongFrameException異常,為false,讀取完整個幀再報異常

delimiter:分隔符

二、FixedLengthFrameDecoder

FixedLengthFrameDecoder是固定長度解碼器,它能夠按照指定的長度對消息進行自動解碼。
用法如下:
pipeline.addLast(new FixedLengthFrameDecoder(23));//參數為一次接受的數據長度。

總結

以上是生活随笔為你收集整理的Netty 框架学习(二):DelimiterBasedFrameDecoder和FixedLengthFrameDecoder的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。