• Netty——简单创建服务器、客户端通讯


           Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。

      Netty简单来说就是socket通讯,支持多协议的通讯

     对 创建 netty 的过程作了详细的解析

    1、简单创建一个Netty服务器

    package com.netty.test;
    
    import java.net.InetAddress;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    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.Delimiters;
    import io.netty.handler.codec.string.StringDecoder;
    import io.netty.handler.codec.string.StringEncoder;
    
    /**
     * Netty4 服务端代码
     *
     */
    public class HelloWorldServer {
    
        
        public static void main(String[] args) {
            // EventLoop 代替原来的 ChannelFactory
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            
            try {
    ServerBootstrap serverBootstrap
    = new ServerBootstrap();        //创建 一个netty 服务器 // server端采用简洁的连写方式,client端才用分段普通写法。 serverBootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class)              // 指定channel[通道]类型 .childHandler(new ChannelInitializer<SocketChannel>() {    // 指定Handler [操纵者]
    @Override
    public void initChannel(SocketChannel ch) throws Exception { // 以(" ")为结尾分割的 解码器 ch.pipeline().addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); // 字符串 解码 和 编码 默认的 StringDecoder 字符串形式输出 ch.pipeline().addLast("decoder", new StringDecoder()); ch.pipeline().addLast("encoder", new StringEncoder()); ch.pipeline().addLast(new HelloServerHandler());     // 添加自己的对 上传数据的处理 }
    }).option(ChannelOption.SO_KEEPALIVE,
    true);
           ChannelFuture f
    = serverBootstrap.bind(8000).sync();           // 绑定 8000 端口 f.channel().closeFuture().sync(); } catch (InterruptedException e) { } finally { workerGroup.shutdownGracefully(); // 销毁 netty bossGroup.shutdownGracefully(); } } /** * 自己对 处理数据 * * @author flm * 2017年11月10日 */ private static class HelloServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { // 收到消息直接打印输出 System.out.println(ctx.channel().remoteAddress() + " Say : " + msg); // 返回客户端消息 - 我已经接收到了你的消息 ctx.writeAndFlush("server Received your message ! "); } /* * * 覆盖 channelActive 方法 在channel被启用的时候触发 (在建立连接的时候) * * channelActive 和 channelInActive 在后面的内容中讲述,这里先不做详细的描述 */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("RamoteAddress : " + ctx.channel().remoteAddress() + " active !"); ctx.writeAndFlush("Welcome to " + InetAddress.getLocalHost().getHostName() + " service! "); //回复 super.channelActive(ctx); } }

    2、netty 客户端 创建

    package com.netty.test;
    
    import java.net.InetSocketAddress;
    import java.util.Date;
    
    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelPipeline;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioSocketChannel;
    import io.netty.handler.codec.DelimiterBasedFrameDecoder;
    import io.netty.handler.codec.Delimiters;
    import io.netty.handler.codec.string.StringDecoder;
    import io.netty.handler.codec.string.StringEncoder;
    
    /**
     * Netty4 客户端代码
     * 
     */
    public class HelloWorldClient {
    
        public static void main(String args[]) {
    
            // Bootstrap,且构造函数变化很大,这里用无参构造。
            Bootstrap bootstrap = new Bootstrap();
            // 指定channel[通道]类型
            bootstrap.channel(NioSocketChannel.class);
            // 指定Handler [操纵者]
            bootstrap.handler(new ChannelInitializer<Channel>() {
    
                @Override
                protected void initChannel(Channel ch) throws Exception {
                    ChannelPipeline pipeline = ch.pipeline();
                    
                    /*
                     * 这个地方的 必须和服务端对应上。否则无法正常解码和编码
                     * 
                     */
                    pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
                    pipeline.addLast("decoder", new StringDecoder());
                    pipeline.addLast("encoder", new StringEncoder());
    
                    // 客户端的逻辑,自己对数据处理
                    pipeline.addLast(new HelloClientHandler());  
                }
            });
            // 指定EventLoopGroup [事件 组]
            bootstrap.group(new NioEventLoopGroup());
    
            // 连接到本地的8000端口的服务端
            bootstrap.connect(new InetSocketAddress("127.0.0.1", 8000));
    
        }
    
    
    
    
        /**
         * 客户端的逻辑,自己对数据处理
         * 
         * @author flm
         * 2017年11月10日
         */
        private static class HelloClientHandler extends ChannelInboundHandlerAdapter {
            
            /*
             * 监听 服务器 发送来的数据
             */
            @Override
            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    
                System.out.println("Server say : " + msg.toString());
    
            }
    
            /*
             * 启动客户端 时触发
             */
            @Override
            public void channelActive(ChannelHandlerContext ctx) throws Exception {
                System.out.println("Client active ");
                ctx.writeAndFlush("我是 client " + new Date() + "
    ");
                super.channelActive(ctx);
            }
    
            /*
             * 关闭 客户端 触发
             */
            @Override
            public void channelInactive(ChannelHandlerContext ctx) throws Exception {
                System.out.println("Client close ");
                super.channelInactive(ctx);
            }
        }
    }
  • 相关阅读:
    Socket与系统调用深度分析
    AudioRecord::getMinFrameCount
    c++: address argument to atomic operation must be a pointer to _Atomic type
    python秒表,方便测试计时
    Android驱动笔记(13)——PMIC reset介绍
    Android驱动笔记(10)——DOS或BAT脚本语法
    第八章——Linux设备模型(1)
    第四章——IOCTL(1)
    第三章(扩展)——虚拟串口设备
    第三章——字符驱动设备
  • 原文地址:https://www.cnblogs.com/lemon-flm/p/7813484.html
Copyright © 2020-2023  润新知