美文网首页
Netty(一)快速入门实例

Netty(一)快速入门实例

作者: 小左伯爵 | 来源:发表于2020-10-29 22:27 被阅读0次

    1.实例要求

    • netty服务器监听8023端口,客户端发送消息给服务器:hello server,服务器回复:Did you say hello server?
      依赖pom.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>cn.itbin</groupId>
        <artifactId>nettybase</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
            <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-all</artifactId>
                <version>4.1.28.Final</version>
            </dependency>
        </dependencies>
    
    
    </project>
    

    2.客户端代码

    2.1 TelnetClient

    package cn.itbin.client;
    
    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioSocketChannel;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    /**
     * @author chenxiaogao
     * @className TelnetClient
     * @description TODO
     * @date 2020/10/29
     **/
    public class TelnetClient {
        static final String HOST = System.getProperty("host", "127.0.0.1");
        static final int PORT = Integer.parseInt(System.getProperty("port", "8023"));
    
        public static void main(String[] args) throws Exception {
    
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                Bootstrap b = new Bootstrap();
                b.group(group)
                        .channel(NioSocketChannel.class)
                        .handler(new TelnetClientInitializer());
    
                // 开始尝试连接
                Channel ch = b.connect(HOST, PORT).sync().channel();
    
                // 从控制台读取输入
                ChannelFuture lastWriteFuture = null;
                BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
                for (; ; ) {
                    String line = in.readLine();
                    if (line == null) {
                        break;
                    }
    
                    // 发送控制台的输入
                    lastWriteFuture = ch.writeAndFlush(line + "\r\n");
    
                    // 如果用户输入了bye,则在此等待直到服务端关闭连接
                    if ("bye".equals(line.toLowerCase())) {
                        ch.closeFuture().sync();
                        break;
                    }
                }
    
                // 等到所有消息都被flush后再关闭连接
                if (lastWriteFuture != null) {
                    lastWriteFuture.sync();
                }
            } finally {
                group.shutdownGracefully();
            }
        }
    }
    
    

    2.2 TelnetClientInitializer

    package cn.itbin.client;
    
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelPipeline;
    import io.netty.channel.socket.SocketChannel;
    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;
    
    /**
     * @author chenxiaogao
     * @className TelnetClientInitializer
     * @description TODO
     * @date 2020/10/29
     **/
    public class TelnetClientInitializer extends ChannelInitializer<SocketChannel> {
        private static final StringDecoder DECODER = new StringDecoder();
        private static final StringEncoder ENCODER = new StringEncoder();
    
        private static final TelnetClientHandler CLIENT_HANDLER = new TelnetClientHandler();
    
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pipeline = ch.pipeline();
    
    
            //首先添加文本行编解码器
            pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
            pipeline.addLast(DECODER);
            pipeline.addLast(ENCODER);
    
            //然后添加业务逻辑
            pipeline.addLast(CLIENT_HANDLER);
    
        }
    }
    
    

    2.3 TelnetClientHandler

    package cn.itbin.client;
    
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    
    /**
     * @author chenxiaogao
     * @className TelnetClientHandler
     * @description TODO
     * @date 2020/10/29
     **/
    public class TelnetClientHandler extends SimpleChannelInboundHandler<String> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
            System.err.println(msg);
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }
    

    3 服务端代码

    3.1 TelnetServer

    package cn.itbin.server;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    import io.netty.handler.logging.LogLevel;
    import io.netty.handler.logging.LoggingHandler;
    import io.netty.handler.ssl.SslContext;
    import io.netty.handler.ssl.SslContextBuilder;
    import io.netty.handler.ssl.util.SelfSignedCertificate;
    
    /**
     * Simplistic telnet server.
     */
    public final class TelnetServer {
    
        static final int PORT = Integer.parseInt(System.getProperty("port", "8023"));
    
        public static void main(String[] args) throws Exception {
    
            EventLoopGroup bossGroup = new NioEventLoopGroup(1);
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                ServerBootstrap b = new ServerBootstrap();
                b.group(bossGroup, workerGroup)
                 .channel(NioServerSocketChannel.class)
                 .handler(new LoggingHandler(LogLevel.INFO))
                 .childHandler(new TelnetServerInitializer());
    
                b.bind(PORT).sync().channel().closeFuture().sync();
            } finally {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }
    }
    
    

    3.2 TelnetServerInitializer

    package cn.itbin.server;
    
    import io.netty.channel.ChannelHandler;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelPipeline;
    import io.netty.channel.socket.SocketChannel;
    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;
    
    /**
     * @author chenxiaogao
     * @className TelnetServerInitializer
     * @description TODO
     * @date 2020/10/29
     **/
    public class TelnetServerInitializer extends ChannelInitializer<SocketChannel> {
        private static final StringDecoder DECODER = new StringDecoder();
        private static final StringEncoder ENCODER = new StringEncoder();
    
        private static final TelnetServerHandler SERVER_HANDLER = new TelnetServerHandler();
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pipeline = ch.pipeline();
            pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
            // 编解码器是静态的因为他们是可共享的
            pipeline.addLast(DECODER);
            pipeline.addLast(ENCODER);
    
            // 业务逻辑
            pipeline.addLast(SERVER_HANDLER);
    
        }
    }
    
    

    3.3 TelnetServerHandler

    package cn.itbin.server;
    
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelFutureListener;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    
    import java.net.InetAddress;
    import java.util.Date;
    
    /**
     * @author chenxiaogao
     * @className TelnetServerHandler
     * @description TODO
     * @date 2020/10/29
     **/
    public class TelnetServerHandler extends SimpleChannelInboundHandler<String> {
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            // 为新建的连接发送问候
            ctx.write("Welcome to " + InetAddress.getLocalHost().getHostName() + "!\r\n");
            ctx.write("It is " + new Date() + " now.\r\n");
            ctx.flush();
        }
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, String request) throws Exception {
            // Generate and write a response.
            String response;
            boolean close = false;
            if (request.isEmpty()) {
                response = "Please type something.\r\n";
            } else if ("bye".equals(request.toLowerCase())) {
                response = "Have a good day!\r\n";
                close = true;
            } else {
                response = "Did you say '" + request + "'?\r\n";
            }
    
            // 不需要在这里写 ChannelBuffer.
            // 编码器在会将response做转换
            ChannelFuture future = ctx.write(response);
    
            // 在发送"Have a good day!\r\n"后关闭连接
            // 如果客户端发过来的是bye
            if (close) {
                future.addListener(ChannelFutureListener.CLOSE);
            }
        }
    
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) {
            ctx.flush();
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }
    
    

    在客户端控制台输入hello server

    Welcome to DESKTOP-39GQUQV!
    It is Thu Oct 29 22:25:53 CST 2020 now.
    hello server
    Did you say 'hello server'?
    bye
    Have a good day!
    

    相关文章

      网友评论

          本文标题:Netty(一)快速入门实例

          本文链接:https://www.haomeiwen.com/subject/wnocvktx.html