Netty之bind源码分析

本文将对Netty服务端中的bind方法进行分析,该方法是Netty核心的实现,通过本文你将了解Netty是怎样接收请求和处理请求的。1.bind(…)方法之前的文章已经介绍过ServerBootstrap 和相关的方法,这里主要分析的是bind()方法ServerBootstrap bootstrap = new ServerBootstrap();# 绑定端口bootstrap.bind(9000).sync();这里开始分析主流程,bind()方法里面最后会调用doBind().
摘要由CSDN通过智能技术生成

本文将对Netty服务端中的bind方法进行分析,该方法是Netty核心的实现,通过本文你将了解Netty是怎样接收请求和处理请求的。

1.bind(…)方法

  • 之前的文章已经介绍过ServerBootstrap 和相关的方法,这里主要分析的是bind()方法
ServerBootstrap bootstrap = new ServerBootstrap();
# 绑定端口
bootstrap.bind(9000).sync();
  • 这里开始分析主流程,bind()方法里面最后会调用doBind()方法,如下
    private ChannelFuture doBind(final SocketAddress localAddress) {
        # 这里是初始化和注册管道,很重要,下面进行详细分析
        final ChannelFuture regFuture = initAndRegister();
        final Channel channel = regFuture.channel();
        if (regFuture.cause() != null) {
            return regFuture;
        }

        if (regFuture.isDone()) {
            // At this point we know that the registration was complete and successful.
            ChannelPromise promise = channel.newPromise();
            # 2.绑定端口的实现
            doBind0(regFuture, channel, localAddress, promise);
            return promise;
        } else {
            final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);
            regFuture.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    Throwable cause = future.cause();
                    if (cause != null) {
                        promise.setFailure(cause);
                    } else {
                        promise.registered();
                         # 3.绑定端口的实现
                        doBind0(regFuture, channel, localAddress, promise);
                    }
                }
            });
            return promise;
        }
    }

2. final ChannelFuture regFuture = initAndRegister()

  • 接下来我们分析下 initAndRegister()方法干了什么事情,主要分为下面三大步骤
final ChannelFuture initAndRegister() {
        Channel channel = null;
        try {
            # 1.创建一个channel
            channel = channelFactory.newChannel();
            # 2.初始化channel
            init(channel);
        } catch (Throwable t) {
            if (channel != null) {
                channel.unsafe().closeForcibly();
                return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t);
            }
            return new DefaultChannelPromise(new FailedChannel(), GlobalEventExecutor.INSTANCE).setFailure(t);
        }
        # 3.将channel注册到选择器selector上
        ChannelFuture regFuture = config().group().register(channel);
        if (regFuture.cause() != null) {
            if (channel.isRegistered()) {
                channel.close();
            } else {
                channel.unsafe().closeForcibly();
            }
        }
        return regFuture;
    }

2.1 channel = channelFactory.newChannel()

  • newChannel方法中是通过反射来创建服务端的socket,前面的文章分析过bootstrap.channel(NioServerSocketChannel.class),通过该方法创建了NioServerSocketChannel,这里的newChannel实例化了这个类,默认是调用的空构造器
public T newChannel() {
        try {
            # 反射得到NioServerSocketChannel对象
            return constructor.newInstance();
        } catch (Throwable t) {
            throw new ChannelException("Unable to create Channel from class " + constructor.getDeclaringClass(), t);
        }
    }
  • 实例化NioServerSocketChannel对象
 public NioServerSocketChannel() {
        this(newSocket(DEFAULT_SELECTOR_PROVIDER));
    }
# 我们跟到this方法里面,直接到核心部分,如下
protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
        # 这个方法下面分析
        super(parent);
        this.ch = ch;
        # 这里的readInterestOp 其实是连接事件=》SelectionKey.OP_ACCEPT
        this.readInterestOp = readInterestOp;
        try {
            # 我们说Netty是对NIO的封装,这里可以看到NIO中的代码,设置为非阻塞
            ch.configureBlocking(false);
        } catch (IOException e) {
            try {
                ch.close();
            } catch (IOException e2) {
                if (logger.isWarnEnabled()) {
                    logger.warn(
                            "Failed to close a partially initialized socket.", e2);
                }
            }
            throw new ChannelException("Failed to enter non-bl
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值