Netty源码解析一服务端启动

本文详细介绍了Netty 4.1.22服务端启动的过程,从ServerBootstrap的bind方法开始,涉及创建NioServerSocketChannel、初始化、注册和地址绑定四个步骤。在创建过程中,通过channelFactory创建NioServerSocketChannel,并设置了非阻塞模式;初始化时配置option、attrs和handler;注册时选择合适的NioEventLoop并进行事件监听;最后,绑定到指定端口,触发channelActive事件。
摘要由CSDN通过智能技术生成

Netty的版本是4.1.22

我们从ServerBootstrap的bind()方法开始跟踪Netty服务端的启动过程。大致分为以下四步:

  1. 创建NioServerSocketChannel
  2. 初始化NioServerSocketChannel
  3. 注册
  4. 地址绑定

一:创建NioServerSocketChannel

AbstractBootStrap

    public ChannelFuture bind(String inetHost, int inetPort) {
   
        return bind(SocketUtils.socketAddress(inetHost, inetPort));
    }

    public ChannelFuture bind(SocketAddress localAddress) {
   
        validate();
        if (localAddress == null) {
   
            throw new NullPointerException("localAddress");
        }
        return doBind(localAddress);
    }

    private ChannelFuture doBind(final SocketAddress localAddress) {
   
        final ChannelFuture regFuture = initAndRegister(); // 初始化并注册
        ......

    final ChannelFuture initAndRegister() {
   
        Channel channel = null;
        try {
   
            channel = channelFactory.newChannel();
        ......

跟踪来到AbstractBootStrapinitAndRegister(),它调用channelFactorynewChannel来创建channel,那么channelFactory是?在服务端会有这样的代码bootstrap.channel(NioServerSocketChannel.class),指定服务端要创建的channel类型为NioServerSocketChannel,跟踪该方法会发现答案

AbstractBootStrap:
    public B channel(Class<? extends C> channelClass) {
   
        if (channelClass == null) {
   
            throw new NullPointerException("channelClass");
        }
        return channelFactory(new ReflectiveChannelFactory<C>(channelClass));
    }

继续往下跟踪你会发现这么一句this.channelFactory = channelFactory;
channelFactory 指向ReflectiveChannelFactory

来看看 ReflectiveChannelFactory#newChannel()的实现

    @Override
    public T newChannel() {
   
        try {
   
            return clazz.getConstructor().newInstance();
        } catch (Throwable t) {
   
            throw new ChannelException("Unable to create Channel from class " + clazz, t);
        }
    }

反射得到 NioServerSocketChannel 实例。

接下来进入到NioServerSocketChannel来看看它的初始化做了什么

	private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER 
		= SelectorProvider.provider();
		
	public NioServerSocketChannel() {
   
        this(newSocket(DEFAULT_SELECTOR_PROVIDER));
    }

    public NioServerSocketChannel(ServerSocketChannel channel) {
   
        super(null, channel, SelectionKey.OP_ACCEPT);
        config = new NioServerSocketChannelConfig(this, javaChannel().socket());
    }

先来看看 newSocket() 方法:创建一个java.nio.channels.ServerSocketChannel

    private static ServerSocketChannel newSocket(SelectorProvider provider) {
   
        try {
   
            return provider.openServerSocketChannel();
        } catch (IOException e) {
   
            throw new ChannelException(
                    "Failed to open a server socket.", e);
        }
    }
    
//package sun.nio.ch;
    public ServerSocketChannel openServerSocketChannel() throws IOException {
   
        return new ServerSocketChannelImpl(this);
    }

回到构造函数,还创建了NioServerSocketChannelConfig实例,它是tcp的参数配置类。
通过super(null, channel, SelectionKey.OP_ACCEPT)往上。注意这里SelectionKey.OP_ACCEPT,将会在之后 NioServerSocketChannel 注册到selector时监听该事件

AbstractNioMessageChannel:
    protected AbstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
   
        super(parent, ch, readInterestOp);
    }

继续往上

AbstractNioChannel:
    protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值