网站首页 > 开源技术 正文
13.1 NIO
NIO,即非阻塞IO。关键点包括Channel, Selector。
Channel向Selector注册事件,如READ,WRITE,CONNECT。当Selector检测到channel上的相关事件发生时,会通知到应用程序。所谓非阻塞,也并非一点都不阻塞,只是阻塞点发生了变化。
13.2 Reactor
hprose用到一种称为Reactor模式的框架。
Reactor继承自Thread,运行在一个单独的线程里。
Reactor之上有个ReactorGroup,称为组。一个组可包括多个Reactor,即可以有多个独立运行的线程。
这样做的好处是,可以利用多核性质,提高系统性能。一个线程处理若干channel上的事件,各线程又独立运转,因此效率较高,但有时需要注意线程同步问题。
13.3 hprose客户端连接过程
hprose客户端连接服务器从Connector类开始
Connector构造时,生成一个Selector实例,生成一个ReactorGroup组实例,组中可容纳的线程数量由外部传入(reactorThreads变量)。
当外部调用Connector的start()方法时,线程就开始运转了。
run()方法会一直运行,直到线程被打断。在run方法的开始,调了ReactorGroup的start()方法,此时组的线程也开始运行。
当客户端试图连接服务器时,会调用哪个方法呢?会调下面的create方法,
这个方法内,通过SocketChannel.open()生成一个SocketChannel实例channel,并且将channel,handler(外部设置的连接回调),address封装到了一个新Connection实例中。同时配置channel为非阻塞。方法中有个register(conn)调用,
register方法只是简单的将conn置入队列queue中,然后唤醒selector, 为何要唤醒?
到这里,还没有发现是如何连接的。因为还没有见到channel.connect()类似这样的调用,这是连接的关键代码。
看来,连接要在run()循环中去找。
在run()方法中,有调用 process()方法
这个方法中,从queue中取出一个Conection实例,然后调conn.connect()方法,继续探究:
此处,channel向selector注册了事件 OP_CONNECT, 并且调用关键代码 channel.connect(address),到此终于看到客户端是如何连接的。
但调下channel.connect是不是完了呢?还没有。
还需要在Connector.dispatch()方法中,作处理
87行代码selector.select()其实是个阻塞方法,当没有检测到任何事件发生时,会一直阻塞。这就是之前调register()方法,将selector唤醒的原因。若不唤醒,线程可能会一直阻塞。看到这里,就知道NIO非阻塞,其实并不是一点也不阻塞,只是阻塞点发生了变化。但这样的一个变化,节约了程序的执行时间,程序不需要一遍遍轮询数据有没有准备好。
接下来的90-98行代码,是selector处理的一般写法。即获取一个迭代器,遍历,依次检测key的状态,调
it.remove()。
key.isConnectable()为true,说明已经检测到连接好了的事件。
连接好以后,调connect()方法
本方法中,通过调channel.finishConnect()完成连接过程。并且将这个conn注册到reactor中。
为什么要将conn注册到reactor中呢?因为conn虽然连接好了,但接下来需要通过conn发送数据,接收服务器传来的数据,这些操作事件的监听放到哪里去处理呢?可以放到Conector实例内,但这样做一个Connector需要完成多件事,会使效率变慢。所以放到了reactor这样专门处理读写的线程内,reactor其实是一个组实例,在组内,又可以将conn分到不同的线程内,进一步提高执行效率。
到此,完成了连接过程。但是,应用程序又怎么知道连接完成了,因为应用程序知道连接完成以后,就要开始发送数据了。这就是连接回调设置的目的。
猜你喜欢
- 2024-10-30 常见的Socket网络异常场景分析(socket异常连接怎么重置)
 - 2024-10-30 JVM性能调优监控工具jps、jstack、jmap、jhat、hprof使用详解
 - 2024-10-30 一文读懂CPU的层次结构(cpu的结构与原理)
 - 2024-10-30 网络安全学习(5) - hping3 学习(hunter网络安全)
 - 2024-10-30 一文读懂如何查看网络的性能指标(如何查看网络强度)
 - 2024-10-30 如何使用网上公开的exp(如何使用网上邻居)
 - 2024-10-30 C++ Socket 编程(c++ socket教程)
 - 2024-10-30 FM2+ APU 最后逆袭,搭载 USB3.1 技嘉 F2A88XM-D3HP
 - 2024-10-30 hprose for java源码分析-16 服务器启动
 - 2024-10-30 得力DM34ADN国产打印机在银河麒麟系统上安装和设置的方法
 
欢迎 你 发表评论:
- 1590℃北京那些看上去很牛的车牌们!(北京厉害车牌)
 - 1107℃2025年度视频去水印软件TOP5对比:哪款最值得用
 - 683℃《我的世界》不同版本的差异 ——新手向
 - 595℃新疆话里的“虫子”
 - 516℃中兴光猫 Telnet下设置大全(中兴光猫命令大全)
 - 513℃蓝牙设备配对失败的系统性解决方案与技术解析
 - 510℃未备份电脑文件数据恢复的七种方法
 - 488℃工艺管道常用英文缩写 英汉对照
 
- 最近发表
 
- 标签列表
 - 
- jdk (81)
 - putty (66)
 - rufus (78)
 - 内网穿透 (89)
 - okhttp (70)
 - powertoys (74)
 - windowsterminal (81)
 - netcat (65)
 - ghostscript (65)
 - veracrypt (65)
 - asp.netcore (70)
 - wrk (67)
 - aspose.words (80)
 - itk (80)
 - ajaxfileupload.js (66)
 - sqlhelper (67)
 - express.js (67)
 - phpmailer (67)
 - xjar (70)
 - redisclient (78)
 - wakeonlan (66)
 - tinygo (85)
 - startbbs (72)
 - webftp (82)
 - vsvim (79)
 
 

本文暂时没有评论,来添加一个吧(●'◡'●)