netty ------------ 如果selector检测到一个channel可以读了
-----------------一个NioEventLoopGroup 的初始化的时候,会初始化一个 NioEventLoop数组,每个NioEventLoop在初始化的时候,会open一个selector放到自己的属性中,再开启一个线程exector,然后调用Run方法,实际上调用的是NioEventLoop的run方法,在这个run
方法里面,执行的是一个for循环,不停的用那个selector来select注册到上面去的channel,然后根据channel的状态,处理key。
private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) {
final AbstractNioChannel.NioUnsafe unsafe = ch.unsafe();
if (!k.isValid()) {
final EventLoop eventLoop;
try {
eventLoop = ch.eventLoop();
} catch (Throwable ignored) {
return;
}
if (eventLoop != this || eventLoop == null) {
return;
}
unsafe.close(unsafe.voidPromise());
return;
}
try {
int readyOps = k.readyOps();
if ((readyOps & SelectionKey.OP_CONNECT) != 0) {
int ops = k.interestOps();
ops &= ~SelectionKey.OP_CONNECT;
k.interestOps(ops);
unsafe.finishConnect();
}
if ((readyOps & SelectionKey.OP_WRITE) != 0) {
ch.unsafe().forceFlush();
}
if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {
--------------------如果channel可读,那么调用unsafe的read方法,下面看read方法的逻辑
unsafe.read();
}
} catch (CancelledKeyException ignored) {
unsafe.close(unsafe.voidPromise());
}
}
回顾一下netty的bootstrap的启动:
一、以serverBootStrap为例,
@Override
public final void read() {
final ChannelConfig config = config();
final ChannelPipeline pipeline = pipeline();
final ByteBufAllocator allocator = config.getAllocator();
final RecvByteBufAllocator.Handle allocHandle = recvBufAllocHandle();
allocHandle.reset(config); ByteBuf byteBuf = null;
boolean close = false;
try {
do {
byteBuf = allocHandle.allocate(allocator);
------byteBuf是对nio中的buffer的封装?
allocHandle.lastBytesRead(doReadBytes(byteBuf));
if (allocHandle.lastBytesRead() <= 0) {
byteBuf.release();
byteBuf = null;
close = allocHandle.lastBytesRead() < 0;
if (close) {
readPending = false;
}
break;
} allocHandle.incMessagesRead(1);
readPending = false;
pipeline.fireChannelRead(byteBuf);
byteBuf = null;
} while (allocHandle.continueReading()); allocHandle.readComplete();
pipeline.fireChannelReadComplete(); if (close) {
closeOnRead(pipeline);
}
} catch (Throwable t) {
handleReadException(pipeline, byteBuf, t, close, allocHandle);
} finally {
if (!readPending && !config.isAutoRead()) {
removeReadOp();
}
}
}
}
@Override
protected int doReadBytes(final ByteBuf byteBuf) throws Exception {
final RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle();
allocHandle.attemptedBytesRead(byteBuf.writableBytes());
--------------再往下看
return byteBuf.writeBytes(javaChannel(), allocHandle.attemptedBytesRead());
}
@Override
public int writeBytes(ScatteringByteChannel in, int length) throws IOException {
ensureWritable(length);
----------再往下看
int writtenBytes = setBytes(writerIndex, in, length);
if (writtenBytes > 0) {
writerIndex += writtenBytes;
}
return writtenBytes;
}
@Override
public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
ensureAccessible();
ByteBuffer tmpBuf = internalNioBuffer();
tmpBuf.clear().position(index).limit(index + length);
try {
-----------------------随便找了一个bytebuf的继承类,发现调用的还是nio的channel的read到一个nio的buffer的方法,而这个tmpNiobuf是netty的bytebuf里面的一个属性,是nio的bytebuffer。
return in.read(tmpNioBuf);
} catch (ClosedChannelException ignored) {
return -1;
}
}
JavaChannel把channel中的数据read到bytebuf中之后,调用pipeline.fireChannelRead,让bytebuf从headContext到tailContext流动,head是一个outbound为true的handler,也就是说,是一个为
写这个动作把最后一关的。相反的,tail是为读这个动作把关,但是正常都会在这之间加一个handler处理数据和逻辑,而不会到tail这一步。同理,写也是会在这中间加一个,而不会到head这一步。
netty ------------ 如果selector检测到一个channel可以读了的更多相关文章
- Netty之心跳检测技术(四)
Netty之心跳检测技术(四) 一.简介 "心跳"听起来感觉很牛X的样子,其实只是一种检测端到端连接状态的技术.举个简单的"栗子",现有A.B两端已经互相连接, ...
- 【Netty】利用Netty实现心跳检测和重连机制
一.前言 心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制. 我们用到的很多框架都用到了心跳检测,比如服务注册到 Eureka Server 之后会维 ...
- Netty快速入门(09)channel组件介绍
书接上回,继续介绍组件. ChannelHandler组件介绍 ChannelHandler组件包含了业务处理核心逻辑,是由用户自定义的内容,开发人员百分之九十的代码都是ChannelHandler. ...
- netty深入学习之中的一个: 入门篇
netty深入学习之中的一个: 入门篇 本文代码下载: http://download.csdn.net/detail/cheungmine/8497549 1)Netty是什么 Netty是Java ...
- Netty入门(二):Channel
前言 Netty系列索引: 1.Netty入门(一):ByteBuf 2.Netty入门(二):Channel 在Netty框架中,Channel是其中之一的核心概念,是Netty网络通信的主体,由它 ...
- netty系列之:netty中各不同种类的channel详解
目录 简介 ServerChannel和它的类型 Epoll和Kqueue AbstractServerChannel ServerSocketChannel ServerDomainSocketCh ...
- pytorch中,不同的kernel对不同的feature map进行卷积之后输出某一个channel对应的多个feature map如何得到一个channel的feature map
实际上在卷积操作的时候,比如说,我某一层输出的feature map的size为4713*13 channel的数目为7,设经过某卷积层之后,网络输出的feature map的channel的数目为1 ...
- 通过 Netty、ZooKeeper 手撸一个 RPC 服务
说明 项目链接 微服务框架都包括什么? 如何实现 RPC 远程调用? 开源 RPC 框架 限定语言 跨语言 RPC 框架 本地 Docker 搭建 ZooKeeper 下载镜像 启动容器 查看容器日志 ...
- 使用Netty和动态代理实现一个简单的RPC
RPC(remote procedure call)远程过程调用 RPC是为了在分布式应用中,两台主机的Java进程进行通信,当A主机调用B主机的方法时,过程简洁,就像是调用自己进程里的方法一样.RP ...
随机推荐
- ssh登陆被拒?(云:使用云的网页版远程登陆) 不好用。
设定的密
- Android的组件化和模块化
Android随着业务的增多,而且后续新的需求的增加,代码的修改会变得非常频繁 然后最近在看组件化和模块化 公司的业务没有那么大,所以这种方式我并没有采取 但是还是需要了解下他的使用机制 还有优缺点之 ...
- IntelliJ IDEA 第一个 Scala 程序
IntelliJ 安装完成 Scala 插件后,你需要尝试使用 IntelliJ 来创建并且运行第一个程序. 通常这个程序只是简单的输出 Hello World. 创建一个新工程 在文件下面选择新建, ...
- smarty插件
smarty插件 1.目录:放在Smarty类库下的plugins目录下面(默认存放的都是smarty自带的插件) smarty3.0提供了自定义插件目录的方式: $ ...
- 诡异的楼梯 HDU - 1180
Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向, ...
- Tempter of the Bone HDU - 1010
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it u ...
- 【洛谷p1258】小车问题
(……吓人,心有余悸) 小车问题[传送门] 洛谷算法标签:: (行吧它居然是个二分[解方程的我抖抖发瑟]) 作为一个写了一页演草纸才解出来的方程,显然我要好好写一写(希望不会半途而废) 思路: 先把其 ...
- 2017-2018 ACM-ICPC Latin American Regional Programming Contest D.Daunting device
题意:一个数组n个操作每次先查询p颜色的数量然后求出区间,区间染色成x,然后求最大染色数 题解:odt裸题,多维护一个color个数数组就好了 //#pragma comment(linker, &q ...
- vue组件插槽
vue中子组件内容如何定义为可扩展的呢,就是用slot插槽来实现.如下图 如果<slot></slot>标签有内容,那就默认显示里面的内容,父组件传了就会覆盖此默认的内容.
- SQLServer 2008以上误操作数据库恢复方法—日志尾部备份
原文出处:http://blog.csdn.net/dba_huangzj/article/details/8491327 问题: 经常看到有人误删数据,或者误操作,特别是update和delete的 ...