一、bind方法

详情请见以前的文章:Netty之Channel、NioEventLoopGroup、客户端connect方法总结

bind方法会调用initAndRegister方法

1.1 initAndRegister方法

1.1.1 生成channel的构造方法

  1. channel.newChannel()。通过反射生成了我们显式设置的NioSocketChannel.class对象,反射是用它的无参构造方法生成的。
  2. 无参构造方法级联调用了多个构造参数。在这个过程中,通过jdk自带的spi机制生成了原生nio的socketChannel对象,这个参数最终会在AbstractChannel的构造方法中设置到ch属性中,并且ch会设置成不阻塞
  3. 生成id,unsafe,pipeline等属性并赋值

1.1.2 init方法

  1. 将显示设置的handler配置到pipeline中
  2. 将显示配置的option设置到channel的pipeline中
  3. 将显示配置attr配置到channel中

1.1.3 register方法

这个方法在MultithreadEventLoopGroup类中。

  1. 选择一个EventLoop,调用其register方法
  2. 最终调用jdk原生nio的Channel.register(selector)

问题:服务端selector是在哪里生成的?

1.1.4 注册触发事件

  1. 调用ChannelInitializer.channelRegister()
  2. 内部调用了钩子方法initChannel(),这个就是我们自己写的initChannel()

二、new NioEventLoopGroup()

详情请见以前的文章:揭开BootStrap的神秘面纱

  1. 构造方法最终调用MultithreadEventExecutorGroup;
    线程数nThreads如果没传,则设置为cpuNum*2;
    children:他其实相当于线程池,存放EventLoop,类型为EventExecutor[]类型,数组大小就为nThreads;
  2. 创建nThreads个EventLoop,放到children这个数组中
  3. 来看NioEventLoop构造方法:
    ①创建selector,selector是NioEventLoop的属性。
    ②将其他的值放到属性中,例如Executor等

上面的问题就得到解答了:

在 NioEventLoop构造方法的时候创建了selector

三、客户端发起请求

最终调用原生的channel.connect方法。

不解的地方:

不懂为什么要递归调用pipeline(TailContext、HeadContext)的connect方法?

四、ServerBootstrap

详情请见以前的文章:揭秘ServerBootstrap神秘面纱(服务端ServerBootstrap)

  1. NioServerSocketChannel的创建、服务端Channel(NioServerSocketChannel)的初始化、ChannelPipeline初始化、服务端注册到Selector与客户端过程大致相同
  2. 服务端有两个EventLoopGroup对象;
    boossGroup-连接事件;workerGroup-io事件
  3. bossGroup不断监听客户端连接,当有新连接时,bossGroup就会为此连接初始化各项资源。然后从workerGroup中选中一个EventLoop绑定此连接,接下来的交互就全在此EventLoop中了
  4. 在启动时——bind()方法,用到的group为bossGroup
  5. workerGroup在哪与NioSocketChannel关联呢?——下面给出答案

问题:workerGroup在哪与NioSocketChannel关联呢?

ServerBootstrap中有channelRead方法,里面有childGroup.register(child)——child就是Channel。

  1. 在服务端调用ServerBootstrap.doBind方法时,会调用init()方法,ServerBootstrap重写了init()方法。
  2. 在这个重写的init方法里,为channel的pipeline添加了新的handler——ServerBootstrapAcceptor(ServerBootstrap的内部类)
  3. ServerBootstrapAcceptor的channelRead方法,在接收到连接事件就会触发,它包含了这段代码:
    childGroup.register(child)...
  4. 上述代码中childGroup就是workerGroup

4.1 handler

服务端有两个group:bossGroup和workerGroup。

猜想:bossGroup关心连接事件,workerGroup关心io事件。

关于这个猜想以后再验证

4.2 selector事件轮询

  1. doBind方法——>channel.eventLoop().excute()-SingleThreadEventExecutor.startThread()——>SingleThreadEventExecutor.this.run()
  2. 在上述run方法里,是一个死循环:轮询+事件+唤醒/休眠
  3. 原生nio的selector会有空轮询bug,它的selector.select()方法有问题,不该唤醒的时候有可能会一直唤醒

Netty之Channel、NioEventLoopGroup、客户端connect方法总结相关推荐

  1. 【初识Netty使用Netty实现简单的客户端与服务端的通信操作Netty框架中一些重要的类以及方法的解析】

    一.Netty是什么? Netty 由 Trustin Lee(韩国,Line 公司)2004 年开发 本质:网络应用程序框架 实现:异步.事件驱动 特性:高性能.可维护.快速开发 用途:开发服务器和 ...

  2. java netty wss_netty实现websocket客户端(支持wss安全连接)

    1,客户端启动类 package test3;import io.netty.bootstrap.Bootstrap;import io.netty.buffer.Unpooled;import io ...

  3. netty自定义channel id

    netty自定义channel id.netty custom channel id 搞搞netty时发现默认的id很长,无法直接自定义. 于是我网上搜索了search一下,发现没有相关文章,那就自己 ...

  4. Netty应用实战:客户端重连

    一.什么是客户端的重连? 简单来说,当连接中断时,客户端对运行的服务端进行重新连接. 二.为什么要客户端进行重连? 就是为了防止由于网络或其他原因导致的连接中断. 三.如何实现重连? 3.1 核心思路 ...

  5. python tcp服务器_python实现TCP服务器端与客户端的方法详解

    本文实例讲述了python实现TCP服务器端与客户端的方法.分享给大家供大家参考.具体如下: TCP服务器程序(tsTserv.py): from socket import * from time ...

  6. Http协议之CONNECT方法

    背景: 无意间发现自己的Fiddler有大量的Tunnel To 的host,遂产生了好奇心,点开了这个session查看一番,发现在Fiddler的详细的请求报文中和我们常见的GET和POST方法的 ...

  7. MQTT.fx客户端使用方法

    MQTT.fx是调试MQTT协议一个必备的工具软件,这里归纳粗略介绍下客户端使用方法. 1. 下载安装. 下载安装 这个网上搜一下,就应该能找到不少. 这里提供一下网盘下载链接 链接:https:// ...

  8. php-redis客户端使用方法

    php-redis客户端使用方法 首先配置好环境,这里就不多说了redis服务端,以及redis的PHP扩展包: View Code <?php require 'redis.php'; req ...

  9. SCCM 2012 R2---配置客户端发现方法和边界组

    二.安装SCCM 2012 R2客户端 1.配置SCCM 2012 R2客户端发现方法 安装完成后我们打开SCCM 2012 R2的控制台: 点击左侧栏的"管理"选项,然后展开&q ...

  10. SCCM2012SP1---配置客户端发现方法和边界组

    二.安装SCCM客户端 1.配置SCCM 2012客户端发现方法 安装完成后我们打开SCCM 2012的控制台: 点击左侧栏的"管理"选项,然后展开"层次结构配置&quo ...

最新文章

  1. matlab添加文件到并行池,【Matlab Debugging】使用 addAttachedFiles(pool, files) 指定要附加的必要文件。...
  2. Golang 匿名结构体及测试代码编写技巧
  3. X264码率控制流程分析
  4. android emmc 命令,使用CoreELEC的ceemmc工具将系统写入emmc
  5. MapReduce的基本流程
  6. java 正则表达式 html,java正则表达式语法大全
  7. 计算机专业Java毕业设计(项目+论文+源码)
  8. c语言实现双拼算法,【连载】(开始学习C语言的指针)——乐创DIY C语言讲义——6.1节...
  9. Django cache redis 最全介绍
  10. 微信小程序 实用的公告栏滚动效果
  11. js数组方法及返回值
  12. Canonical标签怎么使用,Canonical标签有什么作用?
  13. 【华为云技术分享】深度理解AI概念、算法及如何进行AI项目开发
  14. Android常用RGB值以及中英文名称
  15. 进程,线程与多核,多cpu之间的关系
  16. 网页跳转(APP内/浏览器)
  17. 三阶PLL环路参数计算
  18. 安卓Android Studio Button按钮background不生效无效问题
  19. jvm系列(十一):JVM演讲PPT分享
  20. 搭建一个代码在线编辑预览工具

热门文章

  1. 如何在信用卡反欺诈检测中使用人工智能和机器学习
  2. android65535错误实现,Android 65535问题的解决方法
  3. 阿里云云计算6 ECS的概念
  4. 价值连城 图灵奖得主Yann LeCun 杨立昆的采访 给AI从业者的建议
  5. 算法:动态规划 最大连续子数组和 Maximum Subarray
  6. 如何解决类似 curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection refused 的问题 #10
  7. 极客大学架构师训练营 系统架构 分布式数据库 Zookeeper 第12课 听课总结
  8. 极客大学架构师训练营--编程的未来 面向对象 依赖倒置原则 -- 第二次作业
  9. 基于近邻法的分类器设计
  10. java 文件上传终止_java文件上传