zoukankan      html  css  js  c++  java
  • 搭建第一个netty程序

    来自action In netty 自己修改一点点 

    主要依赖

         <dependencies>
                <dependency>
                    <groupId>io.netty</groupId>
                    <artifactId>netty-all</artifactId>
                    <version>${netty.version}</version>
                </dependency>
                <dependency>
                    <groupId>nia</groupId>
                    <artifactId>utils</artifactId>
                    <version>2.0-SNAPSHOT</version>
                </dependency>
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>${junit.version}</version>
                </dependency>
            </dependencies>
        </dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-all</artifactId>
            </dependency>
            <dependency>
                <groupId>nia</groupId>
                <artifactId>utils</artifactId>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
            </dependency>
        </dependencies>

    server端代码

    package nia.chapter2.echoserver;
    
    import java.net.InetSocketAddress;
    
    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.FixedLengthFrameDecoder;
    
    /**
     * 代码清单 2-2 EchoServer 类
     *
     * @author <a href="mailto:norman.maurer@gmail.com">Norman Maurer</a>
     */
    public class EchoServer {
        private static final byte SPACE = (byte)' ';
        private final int port;
    
        public EchoServer(int port) {
            this.port = port;
        }
    
        public static void main(String[] args)
            throws Exception {
    //        if (args.length != 1) {
    //            System.err.println("Usage: " + EchoServer.class.getSimpleName() +
    //                " <port>"
    //            );
    //            return;
    //        }
            //设置端口值(如果端口参数的格式不正确,则抛出一个NumberFormatException)
            int port = Integer.parseInt("8888");
            //调用服务器的 start()方法
            new EchoServer(port).start();
        }
    
        public void start() throws Exception {
            final EchoServerHandler serverHandler = new EchoServerHandler();
            //(1) 创建EventLoopGroup
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                //(2) 创建ServerBootstrap
                ServerBootstrap b = new ServerBootstrap();
                b.group(group)
                    //(3) 指定所使用的 NIO 传输 Channel
                    .channel(NioServerSocketChannel.class)
                    //(4) 使用指定的端口设置套接字地址
                    .localAddress(new InetSocketAddress(port))
                    //(5) 添加一个EchoServerHandler到于Channel的 ChannelPipeline
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            //EchoServerHandler 被标注为@Shareable,所以我们可以总是使用同样的实例
                            //这里对于所有的客户端连接来说,都会使用同一个 EchoServerHandler,因为其被标注为@Sharable,
                            //这将在后面的章节中讲到。
                            //长度编码
                            ch.pipeline().addLast(new FixedLengthFrameDecoder(32));
                          
                            ch.pipeline().addLast(serverHandler);
                        }
                    });
                //(6) 异步地绑定服务器;调用 sync()方法阻塞等待直到绑定完成
                ChannelFuture f = b.bind().sync();
                System.out.println(EchoServer.class.getName() +
                    " started and listening for connections on " + f.channel().localAddress());
                //(7) 获取 Channel 的CloseFuture,并且阻塞当前线程直到它完成
                f.channel().closeFuture().sync();
            } finally {
                //(8) 关闭 EventLoopGroup,释放所有的资源
                group.shutdownGracefully().sync();
            }
        }
        
        
    }

    对应的serverhandler

    package nia.chapter2.echoserver;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelFutureListener;
    import io.netty.channel.ChannelHandler.Sharable;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    import io.netty.util.CharsetUtil;
    
    /**
     * 代码清单 2-1 EchoServerHandler
     *
     * @author <a href="mailto:norman.maurer@gmail.com">Norman Maurer</a>
     */
    //标示一个ChannelHandler可以被多个 Channel 安全地共享
    @Sharable
    public class EchoServerHandler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ByteBuf in = (ByteBuf) msg;
            //将消息记录到控制台
            System.out.println(
                    "Server received: " + in.toString(CharsetUtil.UTF_8));
            //将接收到的消息写给发送者,而不冲刷出站消息
            //ctx.write(in);
        }
    
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx)
                throws Exception {
            //将未决消息冲刷到远程节点,并且关闭该 Channel
            ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
                    .addListener(ChannelFutureListener.CLOSE);
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx,
            Throwable cause) {
            //打印异常栈跟踪
            cause.printStackTrace();
            //关闭该Channel
            ctx.close();
        }
    }

    clien端代码以及handler

    package nia.chapter2.echoclient;
    
    import io.netty.bootstrap.Bootstrap;
    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.NioSocketChannel;
    import io.netty.handler.codec.FixedLengthFrameDecoder;
    import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
    
    import java.net.InetSocketAddress;
    
    /**
     * 代码清单 2-4 客户端的主类
     *
     * @author <a href="mailto:norman.maurer@gmail.com">Norman Maurer</a>
     */
    public class EchoClient {
        private final String host;
        private final int port;
    
        public EchoClient(String host, int port) {
            this.host = host;
            this.port = port;
        }
    
        public void start()
            throws Exception {
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                //创建 Bootstrap
                Bootstrap b = new Bootstrap();
                //指定 EventLoopGroup 以处理客户端事件;需要适用于 NIO 的实现
                b.group(group)
                    //适用于 NIO 传输的Channel 类型
                    .channel(NioSocketChannel.class)
                    //设置服务器的InetSocketAddress
                    .remoteAddress(new InetSocketAddress(host, port))
                    //在创建Channel时,向 ChannelPipeline中添加一个 EchoClientHandler实例
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch)
                            throws Exception {
                            
                            //长度编码
                              ch.pipeline().addLast(
                                      new FixedLengthFrameDecoder(32));
                            
                            ch.pipeline().addLast(
                                 new EchoClientHandler());
                        }
                    });
                //连接到远程节点,阻塞等待直到连接完成
                ChannelFuture f = b.connect().sync();
                //阻塞,直到Channel 关闭
                f.channel().closeFuture().sync();
            } finally {
                //关闭线程池并且释放所有的资源
                group.shutdownGracefully().sync();
            }
        }
    
        public static void main(String[] args)
                throws Exception {
    //        if (args.length != 2) {
    //            System.err.println("Usage: " + EchoClient.class.getSimpleName() +
    //                    " <host> <port>"
    //            );
    //            return;
    //        }
    
            final String host = "127.0.0.1";
            final int port = Integer.parseInt("8888");
            new EchoClient(host, port).start();
        }
    }
    package nia.chapter2.echoclient;
    
    import java.nio.charset.Charset;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandler.Sharable;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.util.CharsetUtil;
    
    /**
     * 代码清单 2-3 客户端的 ChannelHandler
     *
     * @author <a href="mailto:norman.maurer@gmail.com">Norman Maurer</a>
     */
    @Sharable
    //标记该类的实例可以被多个 Channel 共享
    public class EchoClientHandler
        extends SimpleChannelInboundHandler<ByteBuf> {
        @Override
        public void channelActive(ChannelHandlerContext ctx) {
            //当被通知 Channel是活跃的时候,发送一条消息
            
                for(int i = 0 ;i<1000;i++) {
    //                ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!",
    //                        CharsetUtil.UTF_8));
                    
                    ctx.writeAndFlush(getByteBuffer(ctx));
                    
                }
                
        }
    
        private ByteBuf getByteBuffer(ChannelHandlerContext ctx) {        
            byte[] bytes = "你好,我的名字是1234567!".getBytes(Charset.forName("utf-8"));        
            ByteBuf buffer = ctx.alloc().buffer();        
            buffer.writeBytes(bytes);        
            return buffer;    
        }
    
        @Override
        public void channelRead0(ChannelHandlerContext ctx, ByteBuf in) {
            //记录已接收消息的转储
            System.out.println(
                    "Client received: " + in.toString(CharsetUtil.UTF_8));
        }
    
        @Override
        //在发生异常时,记录错误并关闭Channel
        public void exceptionCaught(ChannelHandlerContext ctx,
            Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
        
        public static void main(String[] args) {
            String a = "trumpnoob";
            System.out.println(a.length());
            System.out.println(a.getBytes().length);
        }
    }

    这里加了编码器 主要指定了字节长度

    判断字节长度使用getbyte.length()

    比较简单的处理粘包和粘包的情况

  • 相关阅读:
    CSS浮动(float、clear)通俗讲解
    JAVA 类的加载
    数据库操作 delete和truncate的区别
    正则表达式 匹配相同数字
    Oracle EBS OM 取消订单
    Oracle EBS OM 取消订单行
    Oracle EBS OM 已存在的OM订单增加物料
    Oracle EBS OM 创建订单
    Oracle EBS INV 创建物料搬运单头
    Oracle EBS INV 创建物料搬运单
  • 原文地址:https://www.cnblogs.com/chenyangwang/p/11906162.html
Copyright © 2011-2022 走看看