zoukankan      html  css  js  c++  java
  • java网络通信:netty

    Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

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

    本文示例采用netty 5.0。上代码.

    服务端:

    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    
    public class TimeServer {
    
        public void bind(int port) throws Exception {
            // 配置服务端的NIO,循环事件线程组
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                ServerBootstrap b = new ServerBootstrap();//配置类
                //NioServerSocketChannel作为channel类,它的功能对应于JDK NIO类库中的ServerSocketChannel
                b.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class)
                        .option(ChannelOption.SO_BACKLOG, 1024)
                        .childHandler(new TimeServerHandler());//绑定事件处理类
                // 绑定端口,同步等待成功
                ChannelFuture f = b.bind(port).sync();
    
                // 等待服务端监听端口关闭
                f.channel().closeFuture().sync();
            } finally {
                // 优雅退出,释放线程池资源
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }
    
        public static void main(String[] args) throws Exception {
            int port = 8080;
            if (args != null && args.length > 0) {
                try {
                    port = Integer.valueOf(args[0]);
                } catch (NumberFormatException e) {
                    // 采用默认值
                }
            }
            new TimeServer().bind(port);
        }
    }

    服务端事务处理类:

    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerAdapter;
    import io.netty.channel.ChannelHandlerContext;
    
    public class TimeServerHandler extends ChannelHandlerAdapter {
      /*当有数据时,自动调用,读取msg*/
        public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
            ByteBuf buf = (ByteBuf) msg;
            byte[] req = new byte[buf.readableBytes()];
            buf.readBytes(req);
            String body = new String(req, "UTF-8");
            System.out.println("The time server receive order : " + body);
            String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new java.util.Date(
                    System.currentTimeMillis()).toString() : "BAD ORDER";
            ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
            ctx.write(resp);
        }
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            ctx.flush();
        }
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        ctx.close();
        }
    }

    客户端:

    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.ChannelFuture;
    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.NioSocketChannel;
    
    public class TimeClient {
        public void connect(int port, String host) throws Exception {
            // 配置客户端NIO线程组
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                Bootstrap b = new Bootstrap();
                b.group(group).channel(NioSocketChannel.class)
                        .option(ChannelOption.TCP_NODELAY, true)
                        .handler(new ChannelInitializer<SocketChannel>() {
    //ChannelInitializer<SocketChannel>匿名类初始化channel的pipeline,将客户端事务处理类加入到队列中 @Override
    public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new TimeClientHandler()); } }); // 发起异步连接操作 ChannelFuture f = b.connect(host, port).sync(); // 当代客户端链路关闭 f.channel().closeFuture().sync(); } finally { // 优雅退出,释放NIO线程组 group.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; if (args != null && args.length > 0) { try { port = Integer.valueOf(args[0]); } catch (NumberFormatException e) { // 采用默认值 } } new TimeClient().connect(port, "127.0.0.1"); } }

    客户端事件处理类:

    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerAdapter;
    import io.netty.channel.ChannelHandlerContext;
    import java.util.logging.Logger;
    
    public class TimeClientHandler extends ChannelHandlerAdapter {
    
        private static final Logger logger = Logger
            .getLogger(TimeClientHandler.class.getName());
    
        private final ByteBuf firstMessage;
        
        public TimeClientHandler() {
            byte[] req = "QUERY TIME ORDER".getBytes();
            firstMessage = Unpooled.buffer(req.length);
            firstMessage.writeBytes(req);
        }
      /*连接成功后,自动发送消息*/
        public void channelActive(ChannelHandlerContext ctx) {
          ctx.writeAndFlush(firstMessage);
        }
      /*有消息返回时,自动调用该函数读取*/
        public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
            ByteBuf buf = (ByteBuf) msg;
            byte[] req = new byte[buf.readableBytes()];
            buf.readBytes(req);
            String body = new String(req, "UTF-8");
            System.out.println("Now is : " + body);
        }
      /*发生异常时,自动调用*/
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            // 释放资源
            logger.warning("Unexpected exception from downstream : "
                + cause.getMessage());
            ctx.close();
        }
    }
  • 相关阅读:
    浏览器驱动器下载地址
    7.pytest测试完成后通过allure生成测试报告
    6.pytest参数化操作
    5.pytest中fixture的使用(params参数)
    5.pytest中fixture的使用(scope参数)
    4.pytest中固定装置setup和teardown
    3.pytest函数级测试用例和类级测试用例
    2.pytest用例设计及运行
    1.pytest环境搭建
    Pycharm 常用快捷键
  • 原文地址:https://www.cnblogs.com/nazhizq/p/6538813.html
Copyright © 2011-2022 走看看