Netty源码剖析——bind()绑定端口的分析-下(三十二)

接上文

Init()会调用addLast(),现在进入到 addLast 方法内查看

@Override
public final ChannelPipeline addLast(EventExccutor(iroup group,String name,ChannelHandler handler){
final AbstractChannelHandlerContext newCtx;
synchronized (this){
checkMultiplicity(handler);
newClx=newContext(group,filterName(name,handler),handler);
addLast0(newCtx);
if (lregistered){
newCtx.setAddPending();
callHandlerCallbackLater(newCtx,true);
retum this;
}
EventExecutorexecutor=newCtx.executor();
if (lexecutor,inEventLoop(){
newCtx.setAddPending();
executor.execute(new Runnable(){
@Override
public void run(){
callHandlerAdded0(newCtx);
}};
return this;
}
}
callHandlerAdded0(newCtx);
retum this;
}

说明:

1)addLast方法,在DefaultChannelPipeline类中,属于pipeline方法的核心

2)会检查该handler 是否符合标准。

3)创建一个 AbstractChanndHandlerContext 对象,ChanndHandlerContext 对象是ChannelHandler 和 ChannelPipeline 之间的关联,每当有 ChannelHandler 添加到 Pipeline 中时,都会创建Context。Context 的主要功能是管理他所关联的Handler和同一个Pipeline中的其他Handler之间的交互。将 Context 添加到链表中。也就是追加到 tail 节点的前面。

4)最后,同步或者异步或者晚点异步的调用 callHandlerAdded 方法

 doBind方法有2个重要的步骤,initAndRegister 说完,接下来看 doBind0 方法,代码如下

private static void doBind(
final ChannelFuture regFuture,final Channel channel,
final SocketAddress localAddress,final ChannelPromise promise){
//This method is invoked before channelRegistered() is triggered. Give user handlers a chance to sct up
//the pipeline in its channelRegistered()implementation. 
channel.eventLoop().execute(new Runnable(){
@Override
public void run(){
if(regFuture.isSuccess()(
//bind方法这里下断点,这里下断点,来玩!!
channel.bind(localAddress,prom ise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
}else{
promise.setFailure(regFuture.cause());
}
}}
);}

说明:
1)该方法的参数为 initAndRegister 的 future,NioServerSocketChannel,端口地址,NioServerSocketChannel 的promise 
2)这里就可以根据前面下的断点,一直debug:
将调用 LoggingHandler 的 invokeBind 方法,最后会追到
//DefaultChannelPipeline 类的bind 
//然后进入到 unsafe.bind方法debug,注意要追踪到
//unsafe.bind,要debug第二回的时候,才能看到. 
public void bind(
@Override ChannelHandlerContextctx,SocketAddresslocalAddress,ChannelPromisepromise)throws Exception{
unsafe.bind(localAddress,promise);
}
继续追踪 AbstractChannel 的
public final void bind(final SocketAddress localAddress,final ChannelPromise promise){
//...
try{
//!!!!小红旗 可以看到,这里最终的方法就是 doBind 方法,执行成功后,执行通道的
fireChannelActive方法,告诉所有的handler,已经成功绑定。
doBind(localAddress);//
}catch(Throwable t){
safeSetFailure(promise,t);
closelfClosed();
return;
}}

3)最终 doBind 就会追踪到 NioServerSocketChannel 的 doBind,说明 Netty 底层使用的是 Nio
@Overide
protected void doBind(SocketAddress localAddress)throws Exception{
if(PlatformDependent.javaVersion()>=7){
javaChannel().bind(localAddress,config.getBacklog();
}else{
javaChannel().socket().bind(localAddress,config.getBacklogO);
}
}



  1. 回到 bind 方法(alt+v),最后一步:safeSetSuccess(promise),告诉 promise 任务成功了。其可以执行监听器的方法了。到此整个启动过程已经结束了
  2. 继续 alt+V服务器就回进入到(NioEventLoop类)一个循环代码,进行监听
@Override

protected void run(){

for (;;)(

try{

}

 

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值