端口绑定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//AbstractBootstrap.java
private static void doBind0(
final ChannelFuture regFuture, final Channel channel,
final SocketAddress localAddress, final ChannelPromise promise) {
//把绑定接口的方法做成一个Task 扔到事件执行器 中执行
channel.eventLoop().execute(new Runnable() {
@Override
public void run() {
if (regFuture.isSuccess()) {
channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
} else {
promise.setFailure(regFuture.cause());
}
}
});
}
- 【11】具体实现绑定方法在AbstractChannel#bind()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
@Override public final void bind(final SocketAddress localAddress, final ChannelPromise promise) { assertEventLoop(); if (!promise.setUncancellable() || !ensureOpen(promise)) { return; } ... //false boolean wasActive = isActive(); try { doBind(localAddress); } catch (Throwable t) { ... } if (!wasActive && isActive()) { invokeLater(new Runnable() { @Override public void run() { pipeline.fireChannelActive(); } }); } safeSetSuccess(promise); }
- 【12】底层是使用了jdk底层进行绑定
- 【17】判断是否绑定了
isactive
方法也是用jdk地层实现的javaChannel().socket().isBound();
-
【21】完成绑定后发送事件
1 2 3 4
public void channelActive(ChannelHandlerContext ctx) throws Exception { ctx.fireChannelActive(); readIfIsAutoRead(); }
- 【2】传播channel激活事件
-
【3】层层的调用最终实现方式是在
AbstractNioChannel#doBeginRead
1 2 3 4 5 6 7 8 9 10 11 12 13
//AbstractNioChannel.java protected void doBeginRead() throws Exception { final SelectionKey selectionKey = this.selectionKey; if (!selectionKey.isValid()) { return; } ... final int interestOps = selectionKey.interestOps(); if ((interestOps & readInterestOp) == 0) { selectionKey.interestOps(interestOps | readInterestOp); } }
获取服务端channel注册到selector上的selectionKey,然后获取这个key的interestOps 然后判断这个interestOps是否是0(SelectionKey.OP_ACCEPT,具体请见【1-2-1.Netty源码:服务端NioServerSocketChanne构造方法】)如果等于0 做个或操绑定Accept事件,再重新绑定到selectionKey。