Java Netty Codecs 程序「建议收藏」

服务端定义了一个Handler和三个Decoder。Handler接收客户端的信息,然后传递给decoder过滤处理。1.服务端packagecom.learn.netty.codecs;importio.netty.bootstrap.ServerBootstrap;importio.netty.channel.ChannelFuture;importio.netty.channel.ChannelInitializer;importio.netty.channel.E.

大家好,又见面了,我是你们的朋友全栈君。

服务端定义了一个Handler和三个Decoder。Handler接收客户端的信息,然后传递给decoder过滤处理。

 

1.服务端

package com.learn.netty.codecs;

import io.netty.bootstrap.ServerBootstrap;
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.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;

import java.net.InetSocketAddress;

public class Server {
    public static void main(String[] args) throws Exception {
        ServerBootstrap bootstrap = new ServerBootstrap();
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            bootstrap.group(group).channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(8888))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            socketChannel.pipeline().addFirst(new ReadHandler())
                                    .addLast(new FixedLengthDecoder())
                                    .addLast(new LoggingDecoder())
                                    .addLast(new LastDecoder());
                        }
                    });
            ChannelFuture future = bootstrap.bind().sync();
            future.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully().sync();
        }
    }
}

 

2.服务端Handler

package com.learn.netty.codecs;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class ReadHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        System.out.println("Received: " + buf.readableBytes());
        ctx.fireChannelRead(buf);
    }
}

 

3.服务端 FixedLengthDecoder

客户端传递的是数字,Java中每个int类型4字节,读取转成字符串,然后传递到下一个Decoder。

package com.learn.netty.codecs;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.CharsetUtil;

import java.util.List;

public class FixedLengthDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        System.out.println("Fixed: " + byteBuf.readableBytes());
        StringBuilder sb = new StringBuilder();
        while (byteBuf.readableBytes() >= 4) {
            // 读取才能向后传递
            sb.append(byteBuf.readInt());
        }
        list.add(Unpooled.copiedBuffer(sb, CharsetUtil.UTF_8));
    }
}

 

4.服务端 LoggingDecoder

将所有信息记录下来,然后传递接收的数字并追加一个字符串。

package com.learn.netty.codecs;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.CharsetUtil;

import java.nio.charset.Charset;
import java.util.List;

public class LoggingDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        System.out.println("Logging: " + byteBuf.readableBytes());
        String num = "";
        while (byteBuf.isReadable()) {
            // 读取才能向后传递
            num = byteBuf.readCharSequence(byteBuf.readableBytes(), Charset.defaultCharset()).toString();
            System.out.println(num);
        }
        list.add(Unpooled.copyInt(Integer.parseInt(num)));

        ByteBuf bf = Unpooled.copiedBuffer("Netty", CharsetUtil.UTF_8);
        list.add(bf);
    }
}

 

5.服务端 LastDecoder

读取接收的数字和字符串。

package com.learn.netty.codecs;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.nio.charset.Charset;
import java.util.List;

public class LastDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
        // Decoder没有读取会被调用多次
        // System.out.println("Last readable: " + byteBuf.readableBytes());
        // System.out.println(byteBuf.toString(Charset.defaultCharset()));

        System.out.println("Last readable: " + byteBuf.readableBytes());
        if (byteBuf.readableBytes() == 4) {
            int num = byteBuf.readInt();
            System.out.println("num: " + num);
        } else {
            ByteBuf buf = byteBuf.readBytes(byteBuf.readableBytes());
            System.out.println(buf.toString(Charset.defaultCharset()));
        }
    }
}

 

6.客户端

向服务端传递 6 个 int。

package com.learn.netty.codecs;


import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.net.InetSocketAddress;

public class Client {
    public static void main(String[] args) throws Exception {
        Bootstrap bootstrap = new Bootstrap();
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            bootstrap.group(group);
            bootstrap.channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    socketChannel.pipeline().addFirst(new ChannelInboundHandlerAdapter(){
                        @Override
                        public void channelActive(ChannelHandlerContext ctx) throws Exception {
                            System.out.println("client active");
                            ctx.writeAndFlush(Unpooled.copyInt(1));
                            ctx.writeAndFlush(Unpooled.copyInt(2));
                            ctx.writeAndFlush(Unpooled.copyInt(3));
                            ctx.writeAndFlush(Unpooled.copyInt(4));
                            ctx.writeAndFlush(Unpooled.copyInt(5));
                            ctx.writeAndFlush(Unpooled.copyInt(6));
                        }
                    });
                }
            }).remoteAddress(new InetSocketAddress("127.0.0.1", 8888));
            ChannelFuture future = bootstrap.connect().sync();
            future.channel().close().sync();
        } finally {
            group.shutdownGracefully().sync();
        }
    }
}

 

结果:

Received: 24
Fixed: 24
Logging: 6
123456
Last readable: 4
num: 123456
Last readable: 5
Netty

 

原文地址: https://www.zhblog.net/go/java/tutorial/java-netty-codecs?t=597

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/128663.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • vue前端面试题2022_前端常见面试题

    vue前端面试题2022_前端常见面试题然后现在也是找了一些在Vue方面经常出现的面试题,留给自己查看消化,也分享给有需要的小伙伴。如果文章中有出现纰漏、错误之处,还请看到的小伙伴留言指正,先行谢过。以下↓1.说一下Vue的双向绑定数据的原理vue实现数据双向绑定主要是:采用数据劫持结合“发布者-订阅者”模式的方式,通过Object.defineProperty()来劫持各个属性的setter、…

  • select into from 与 insert into select用法详解

    select into from 与 insert into select用法详解selectintofrom和insertintoselect都被用来复制表结构和表中数据,两者的主要区别为:selectintofrom要求目标表不存在,因为在插入时会自动创建。insertintoselectfrom要求目标表已存在数据库中。一、INSERTINTOSELECT语句  1、语句形式为:

  • CSP-J2011模拟赛#3—-考试总结

    CSP-J2011模拟赛#3—-考试总结​​​​​T1-面试说起这道题其实我刚看到的时候感觉挺简单的——但不得不说木有事情是绝对的;我看到一个0分时我蒙了。错因(挺可悲):没清空计数器加上一个a=b=c=d=0后一百分拿到手。不得不说细节决定成败-;反思:注意严谨做题,注意细节(例如:清空计数器)​​​​​T2-Excel计数器思路:刚看到这道题的时候几乎没有思路(大概我太菜了)。盲点主要集中在不会把数字转成字母以下klz大佬的方法(看懂了)——先用一个数​​​​​组把A-Z存起来,接着用一个while数…

  • 学计算机编程应该先学什么,如何自学计算机编程,学编程应该先学什么

    学计算机编程应该先学什么,如何自学计算机编程,学编程应该先学什么我以前学过但后来放弃了我可以给你点建议希望对你有用!!1.编程一般来说还是先学C语言,其实你不学C直接学C++也行,因为在C++中也包含很多C语。。但是我还是建议先学c.虽然要多花点时间但是对你以后过渡到C++和理解一些编程的基础知识,基本概念是很有好处的。学好了C之后就可以选择学java,c++,C#等。。。虽然语言多,但是他们都基于C只是有些地方不同,你可以根据你的就业方向选择一门学精,一…

  • java游戏激活成功教程版盒子,37游戏盒子-37游戏盒子最新版 v4.0.0.4 官方版[通俗易懂]

    java游戏激活成功教程版盒子,37游戏盒子-37游戏盒子最新版 v4.0.0.4 官方版[通俗易懂]37游戏盒子37游戏盒子最新版是一款提供游戏下载辅助软件。37游戏盒子最新版内置海量游戏而且不断更新,让玩家不必到处找游戏。而且还会自动去检测游戏所需要的软件和硬件环境,玩家只需轻松一点,就可以实现游戏的下载、安装、运行全部过程。37游戏盒子最新版特色说明:1、内置海量游戏,不断更新,不必到处找游戏。2、只需轻松一点,实现游戏的下载、安装、运行,减少用户麻烦,节省玩家时间。3、斥资千万,全新搭建智…

  • 接口 DatabaseMetaData.getColumns

    接口 DatabaseMetaData.getColumns来源:http://docs.oracle.com/javase/1.4.2/docs/api/java/sql/DatabaseMetaData.html#getColumns(java.lang.String,java.lang.String,java.lang.String,java.lang.String)http://www.cjsdn.net/doc/jdk50/

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号