87

一个简单的Netty-EchoDemo

 4 years ago
source link: https://www.tuicool.com/articles/vUbmeay
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本博客猫叔的博客,转载请申明出处

阅读本文约 “4分钟”

适读人群:Java-Netty 初级

Echo简易通讯案例

版本:netty 4.1.*

申明:本文旨在重新分享讨论Netty官方相关案例,添加部分个人理解与要点解析。

这个是 InChat 的案例 地址 ,里面补充了详细的注释,比起官方会容易看一点。

官方案例地址:https://netty.io/4.1/xref/io/netty/example/echo/package-summary.html

正文

  • EchoClient(客户端)
  • EchoClientHandler
  • EchoServer(服务端)
  • EchoServerHandler

要点介绍

  • SslContext

官方介绍:https://netty.io/4.1/api/io/netty/handler/ssl/SslContext.html

公共抽象类,安全套接字协议实现充当工厂SSLEngine和SslHandler。在内部,它通过JDK SSLContext或OpenSSL 实现SSL_CTX,还有关于它的使用方式,如果你需要ssl加密的话

  • SslContextBuilder

官方介绍:https://netty.io/4.1/api/io/netty/handler/ssl/SslContextBuilder.html

用于配置新SslContext以进行创建的构建器,其中包含多个方法这里就不多补充,大家可以去看看

  • InsecureTrustManagerFactory

官方介绍:https://netty.io/4.1/api/io/netty/handler/ssl/util/InsecureTrustManagerFactory.html

在TrustManagerFactory没有任何验证的情况下信任所有X.509证书的不安全因素

注意:切勿TrustManagerFactory在生产中使用它。它纯粹是出于测试目的,因此非常不安全。

  • SelfSignedCertificate

官方介绍:https://netty.io/4.1/api/io/netty/handler/ssl/util/SelfSignedCertificate.html

生成临时自签名证书以进行测试

注意:切勿在生产中使用此类生成的证书和私钥。它纯粹是出于测试目的,因此非常不安全。它甚至使用不安全的伪随机生成器在内部更快地生成

项目源码

  • EchoClient
/**
 * @ClassName EchoClient
 * @Description 一个简单的应答通讯的实例
 * @Author MySelf
 * @Date 2019/8/17 17:56
 * @Version 1.0
 **/
public final class EchoClient {

    //判断是否加密
    static final boolean SSL = System.getProperty("ssl") != null;
    //监听本地服务
    static final String HOST = System.getProperty("host", "127.0.0.1");
    //监听端口
    static final int PORT = Integer.parseInt(System.getProperty("port", "8007"));
    //发送消息的大小,用于EchoClientHandler
    static final int SIZE = Integer.parseInt(System.getProperty("size", "256"));

    public static void main(String[] args) throws Exception {
        //公共抽象类,安全套接字协议实现充当工厂SSLEngine和SslHandler。在内部,它通过JDK SSLContext或OpenSSL 实现SSL_CTX
        final SslContext sslCtx;
        if (SSL){
            //用于配置新SslContext以进行创建的构建器
            sslCtx = SslContextBuilder.forClient()
                    //用于验证远程端点证书的可信管理器
                    //InsecureTrustManagerFactory:在TrustManagerFactory没有任何验证的情况下信任所有X.509证书的不安全因素
                    //注:切勿TrustManagerFactory在生产中使用它。它纯粹是出于测试目的,因此非常不安全。
                    .trustManager(InsecureTrustManagerFactory.INSTANCE).build();
        }else {
            sslCtx = null;
        }
        //事件循环
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY,true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel sc) throws Exception {
                            ChannelPipeline p = sc.pipeline();
                            //了解SslContext的用法
                            if (sslCtx != null){
                                p.addLast(sslCtx.newHandler(sc.alloc(),HOST,PORT));
                            }
                            p.addLast(new EchoClientHandler());
                        }
                    });
            //这个sync后的代码均会执行
            ChannelFuture f = b.connect(HOST,PORT).sync();
            System.out.println("before-----");

            //这个sync后的代码不会执行
            f.channel().closeFuture().sync();
            System.out.println("after-----");
        }finally {
            group.shutdownGracefully();
        }
    }

}
  • EchoClientHandler
/**
 * @ClassName EchoClientHandler
 * @Description TODO
 * @Author MySelf
 * @Date 2019/8/17 18:06
 * @Version 1.0
 **/
public class EchoClientHandler extends ChannelInboundHandlerAdapter {

    private final ByteBuf firstMessage;

    public EchoClientHandler(){
        //获取EchoClient的SIZE
        //Unpooled:ByteBuf通过分配新空间或通过包装或复制现有字节数组,字节缓冲区和字符串来创建新的
        firstMessage = Unpooled.buffer(EchoClient.SIZE);
        for (int i = 0; i < firstMessage.capacity(); i++){
            firstMessage.writeByte((byte)i);
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.writeAndFlush(firstMessage);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.write(msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
  • EchoServer
/**
 * @ClassName EchoServer
 * @Description 服务端
 * @Author MySelf
 * @Date 2019/8/17 18:15
 * @Version 1.0
 **/
public final class EchoServer {

    static final boolean SSL = System.getProperty("ssl") != null;
    static final int PORT = Integer.parseInt(System.getProperty("port", "8007"));

    public static void main(String[] args) throws Exception {
        final SslContext sslCtx;
        if (SSL){
            //SelfSignedCertificate:生成临时自签名证书以进行测试
            SelfSignedCertificate ssc = new SelfSignedCertificate();
            sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
        }else{
            sslCtx = null;
        }

        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        final EchoServerHandler serverHandler = new EchoServerHandler();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG,100)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline p = ch.pipeline();
                            if (sslCtx != null){
                                p.addLast(sslCtx.newHandler(ch.alloc()));
                            }
                            p.addLast(serverHandler);
                        }
                    });

            ChannelFuture f = b.bind(PORT).sync();

            f.channel().closeFuture().sync();

        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }

    }

}
  • EchoServerHandler
/**
 * @ClassName EchoServerHandler
 * @Description TODO
 * @Author MySelf
 * @Date 2019/8/17 18:14
 * @Version 1.0
 **/
@ChannelHandler.Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.write(msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

公众号:Java猫说

学习交流群:728698035

现架构设计(码农)兼创业技术顾问,不羁平庸,热爱开源,杂谈程序人生与不定期干货。

EJFriqR.jpg!web


Recommend

  • 115

    Netty 4.0.53.Final and 4.1.17.Final released by normanmaurer on 08-Nov-2017 I'm happy to announce the latest bug-fix releases for our...

  • 142
    • sylvanassun.github.io 6 years ago
    • Cache

    Netty的那点事儿 | SylvanasSun's Blog

    Netty是一个基于异步与事件驱动的网络应用程序框架,它支持快速与简单地开发可维护的高性能的服务器与客户端。 所谓事件驱动就是由通过各种事件响应来决定程序的流程,在Netty中到处都充满了异步与事件驱动,这种特点使得应用程序可以以任意的顺序响应在任意的时间...

  • 49
    • thinkinjava.cn 5 years ago
    • Cache

    闪电侠 Netty 小册里的骚操作

    前言 即使这是一本小册,但基于“不提笔不读书”的理念,仍然有必要总结一下。此小册对于那些“硬杠 Netty 源码 却不曾在千万级生产环境上使用实操”的用户非常有用。当然,对那些没有 Netty 编程经验的人来说,更为有用。

  • 61
    • blog.einverne.info 5 years ago
    • Cache

    Netty 简单实用

    Netty 是异步、事件驱动的网络框架,可以用于开发高性能的网络服务器程序。 传统的多线程服务端程序是 Blocking (阻塞的),也就是接受客户端连接,读数据,发送数据是阻塞的,线程必须处理完才能继续下一个请求。而 Netty 的 N...

  • 33
    • mushiming.top 5 years ago
    • Cache

    netty原理分析

    Netty是一个高性能、异步事件驱动的NIO框架,它提供了对TCP、UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用户可以方便的主动获取或者通过通知机制获得IO操作结果。

  • 47
    • 掘金 juejin.im 5 years ago
    • Cache

    Java 200+ 面试题补充② Netty 模块

    让我们每天都能看到自己的进步。老王带你打造最全的 Java 面试清单,认真把一件事做到最好。 本文是前文《Java 最常见的 200+ 面试题》的第二个补充模块,第一模块为:《Java 200+ 面试题补充 ThreadLocal 模块》。 1.Netty

  • 37
    • www.tuicool.com 5 years ago
    • Cache

    Netty基础篇:Netty是什么?

    在开始了解Netty是什么之前,我们先来回顾一下,如果我们需要实现一个客户端与服务端通信的程序,使用传统的IO编程,应该如何来实现? IO编程 我们简化下场景:客户端每隔两秒发送一个带有时间戳的"hello world"给服...

  • 28
    • www.tuicool.com 4 years ago
    • Cache

    Java并发 -- Netty线程模型

    BIO即 阻塞式IO ,使用BIO模型,一般会 为每个Socket分配一个独立的线程 为了避免频繁创...

  • 5

    上一篇文章,我们讲到了netty对SOCKS消息提供了SocksMessage对象的封装,并且区分SOCKS4和SOCKS5,同时提供了连接和响应的各种状态。 有了SOCKS消息的封装之后,我们还需要做些什么工作才能搭建一个SOCKS服务器呢? 使用SSH搭建SOCKS服务器...

  • 2

    UDT给了你两种选择,byte stream或者message,到底选哪一种呢?经验告诉我们,只有小学生才做选择题,而我们应该全都要! 类型的定义 UDT的两种类型是怎么定义的呢? 翻看com.barchart.udt包,可以发现这两种类型定义在TypeUDT枚举类中。...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK