Netty源码分析系列之服务端Channel的端口绑定

本文深入分析Netty服务端Channel的端口绑定过程,探讨了Netty如何实现与JDK原生NIO的端口绑定操作,以及何时将服务端channel感兴趣的事件设置为OP_ACCEPT。通过对Netty源码的逐步剖析,揭示了Netty服务端启动的关键步骤和内部逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

扫描下方二维码或者微信搜索公众号菜鸟飞呀飞,即可关注微信公众号,阅读更多Spring源码分析Java并发编程文章。

微信公众号

微信公众号

问题

本文内容是接着前两篇文章写的,有兴趣的朋友可以先去阅读下两篇文章: Netty 源码分析系列之服务端 Channel 初始化Netty 源码分析系列之服务端 Channel 注册

由于 Netty 是对 JDK 原生 NIO 的封装,对比 JDK 原生 NIO 的写法,我们可以先思考一下以下两个问题。

  1. 在 JDK 原生 NIO 写法中,会调用 serverSocketChannel.bind(new InetSocketAddress(port)) 进行端口号的绑定,那么在 Netty 中,绑定端口号的操作又是在什么地方实现的呢?

  2. 在 JDK 原生的 NIO 写法中,在将 ServerSocketChannel 注册到多路复用器 Selector 上时,就将 ServerSocketChannel 感兴趣的事件设置为了 OP_ACCEPT 事件,而 Netty 中,将 channel 注册到 Selector 时,将 channel 感兴趣的事件设置的是 0 ,即对任何事件都不感兴趣。那么在 Netty 中,又是什么时候将服务端 channel 感兴趣的事件设置为 OP_ACCEPT 的呢?

JDK 原生 NIO 的写法如下。

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 轮询器,不同的操作系统对应不同的实现类
Selector selector = Selector.open();
// 绑定端口
serverSocketChannel.bind(new InetSocketAddress(8080));
serverSocketChannel.configureBlocking(false);
// 将服务端channel注册到轮询器上,并告诉轮询器,自己感兴趣的事件是ACCEPT事件
serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);

端口绑定

当调用 serverBootstrap.bind(port) 时,会调用到 AbstractBootstrap.doBind(final SocketAddress localAddress) 方法。在 doBind(localAddress) 方法中,会先调用 initAndRegister() 方法来初始化服务端 Channel 以及将服务端 channel 注册到多路复用器上,该方法详细的源码分析已经在前两篇文章中Netty 源码分析系列之服务端 Channel 初始化Netty 源码分析系列之服务端 Channel 注册 分析过了,今天将接着分析 doBind(localAddress) 后面的逻辑。doBind(localAddress)方法的源码如下

private ChannelFuture doBind(final SocketAddress localAddress) {
    //初始化和注册
    final ChannelFuture regFuture = initAndRegister();
    final Channel channel = regFuture.channel();
    if (regFuture.cause() != null) {
        return regFuture;
    }
    // 无论是进入if还是进入else,最终均会执行doBind0()
    if (regFuture.isDone()) {
        // At this point we know that the registration was complete and successful.
        ChannelPromise promise = channel.newPromise();
        doBind0(regFuture, channel, localAddress, promise);
        return promise;
    } else {
        // Registration future is almost always fulfilled already, but just in case it's not.
        final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);
        regFuture.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelF
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值