zoukankan      html  css  js  c++  java
  • Netty学习之客户端创建

    一、客户端开发时序图

      

      图片来源:Netty权威指南(第2版)

    二、Netty客户端开发步骤

      使用Netty进行客户端开发主要有以下几个步骤:

      1、用户线程创建Bootstrap

    Bootstrap b = new Bootstrap();

      Bootstrap是Socket客户端创建工具类,通过API设置创建客户端相关的参数,异步发起客户端连接。

      2、创建处理客户端连接、IO读写的Reactor线程组NioEventLoopGroup

    EventLoopGroup group = new NioEventLoopGroup();

      3、通过Bootstrap的ChannelFactory和用户指定的Channel类型创建用于客户端连接的NioSocketChannel

    b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true)

      此处的NioSocketChannel类似于Java NIO提供的SocketChannel。

      4、创建默认的channel Handler pipeline

    b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true)
     .handler(new ChannelInitializer<SocketChannel>()
      {
           @Override
           public void initChannel(SocketChannel ch) throws Exception
           {
             ch.pipeline().addLast(new HelloClientHandler());
            }
      });

      用于调度和执行网络事件。

      5、异步发起TCP连接

     // 发起异步连接操作
     ChannelFuture f = b.connect(host, port).sync();

      SocketChannel执行connect()操作后有以下三种结果:

    • 连接成功,然会true;
    • 暂时没有连接上,服务器端没有返回ACK应答,连接结果不确定,返回false。此种结果下,需要将NioSocketChannel中的selectionKey设置为OP_CONNECT,监听连接结果;
    • 接连失败,直接抛出I/O异常

      6、由多路复用器在I/O中轮询个Channel,处理连接结果

      7、如果连接成功,设置Future结果,发送连接成功事件,触发ChannelPipeline执行

      8、由ChannelPipeline调度执行系统和用户的ChannelHandler,执行业务逻辑

    三、Netty客户端开发示例代码

      需求:客户端端实现,连接服务器端,并向服务器端发送hello Netty。(注:本代码使用的netty是netty-all-5.0.0.Alpha1-sources.jar版本)

      服务器端代码见Netty学习之服务器端创建

      客户端代码:

    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 HelloClient
    {
        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>()
                        {
                            @Override
                            public void initChannel(SocketChannel ch) throws Exception
                            {
                                ch.pipeline().addLast(new HelloClientHandler());
                            }
                        });
    
                // 发起异步连接操作
                ChannelFuture f = b.connect(host, port).sync();
    
                // 等待客户端链路关闭
                f.channel().closeFuture().sync();
            } finally
            {
                group.shutdownGracefully();
            }
        }
        public static void main(String[] args) throws Exception
        {
            int port = 8080;
            new HelloClient().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;
    
    public class HelloClientHandler  extends ChannelHandlerAdapter
    {
    
        private final ByteBuf message;
        
        public HelloClientHandler()
        {
            byte[] req="hello Netty".getBytes();
            message=Unpooled.buffer(req.length);
            message.writeBytes(req);
        }
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception
        {
            ctx.writeAndFlush(message);
        }
        
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
        {
            ctx.close();
        }
    }

      程序运行结果:

      

    四、参考资料

      1、Netty权威指南

  • 相关阅读:
    ASP.NET中存取图片到数据库的示例(C#)
    解决:通过asp.net 调用FlashPrinter.exe把所有可打印的文件转换成swf文件
    vs命令提示,类生成.dll文件 .snk文件
    asp.net 为指定的图片生成缩图
    asp.net自定义错误处理页面的几种方法。
    ACCESS高效分页
    C# 读取excel数据的两个方法
    ucenter asp.net接口源码,有用户中心、站内短信接口
    存储过程中的top+变量
    测试
  • 原文地址:https://www.cnblogs.com/xujian2014/p/5707823.html
Copyright © 2011-2022 走看看