上一篇博客【Netty源码学习】BootStrap中我们介绍了客户端使用的启动服务,接下来我们介绍一下服务端使用的启动服务。

总体来说ServerBootStrap有两个主要功能:

(1)调用父类AbstractBootStrap的initAndregister函数将NioServerSocketChannel注册到Selector中,上一篇博客中我们已经介绍了。

(2)调用父类的doBind0函数绑定端口,并在线程池中执行。

ServerBootStrap使用如下:

ServerBootstrap serverBootstrap = new ServerBootstrap().group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
					.localAddress(port).childHandler(new ChannelInitializer<SocketChannel>() {

						@Override
						protected void initChannel(SocketChannel ch) throws Exception {
							 ch.pipeline().addLast("decoder", new StringDecoder());
	                            ch.pipeline().addLast("encoder", new StringEncoder());
	                            ch.pipeline().addLast(new ServerHandler());
						}
					}).option(ChannelOption.SO_BACKLOG, 128)
	                .childOption(ChannelOption.SO_KEEPALIVE, true);
			ChannelFuture future = serverBootstrap.bind(port).sync();   

在构造函数中只是一些参数值的设置,真正开始操作的地方是调用 serverBootstrap.bind(port).sync(),从bind函数开始来实现我们刚才讲的两个主要功能。

首先绑定端口函数调用。

	public ChannelFuture bind(int inetPort) {
        return bind(new InetSocketAddress(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 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();
            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(ChannelFuture future) throws Exception {
                    Throwable cause = future.cause();
                    if (cause != null) {
                        // Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an
                        // IllegalStateException once we try to access the EventLoop of the Channel.
                        promise.setFailure(cause);
                    } else {
                        // Registration was successful, so set the correct executor to use.
                        // See https://github.com/netty/netty/issues/2586
                        promise.registered();

                        doBind0(regFuture, channel, localAddress, promise);
                    }
                }
            });
            return promise;
        }
    }

在绑定端口操作是我们会看到如下操作final ChannelFuture regFuture = initAndRegister();,initAndRegister就是实现Channel注册到Selector中,前一篇博客中我们已经介绍。接下来我们介绍doBind0函数,服务端绑定端口到本机服务器上。

private static void doBind0(
            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 set up
        // the pipeline in its channelRegistered() implementation.
        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());
                }
            }
        });
    }

通过上面的代码我们知道doBind0的操作就是创建一个新线程,放到线程池中操作,通过Channel来绑定地址。

【Netty源码学习】ServerBootStrap的更多相关文章

  1. Netty 源码学习——EventLoop

    Netty 源码学习--EventLoop 在前面 Netty 源码学习--客户端流程分析中我们已经知道了一个 EventLoop 大概的流程,这一章我们来详细的看一看. NioEventLoopGr ...

  2. Netty源码学习系列之4-ServerBootstrap的bind方法

    前言 今天研究ServerBootstrap的bind方法,该方法可以说是netty的重中之重.核心中的核心.前两节的NioEventLoopGroup和ServerBootstrap的初始化就是为b ...

  3. 【Netty源码学习】DefaultChannelPipeline(三)

    上一篇博客中[Netty源码学习]ChannelPipeline(二)我们介绍了接口ChannelPipeline的提供的方法,接下来我们分析一下其实现类DefaultChannelPipeline具 ...

  4. 【Netty源码学习】ChannelPipeline(一)

    ChannelPipeline类似于一个管道,管道中存放的是一系列对读取数据进行业务操作的ChannelHandler. 1.ChannelPipeline的结构图: 在之前的博客[Netty源码学习 ...

  5. Netty 源码学习——客户端流程分析

    Netty 源码学习--客户端流程分析 友情提醒: 需要观看者具备一些 NIO 的知识,否则看起来有的地方可能会不明白. 使用版本依赖 <dependency> <groupId&g ...

  6. 【Netty源码学习】EventLoopGroup

    在上一篇博客[Netty源码解析]入门示例中我们介绍了一个Netty入门的示例代码,接下来的博客我们会分析一下整个demo工程运行过程的运行机制. 无论在Netty应用的客户端还是服务端都首先会初始化 ...

  7. (一)Netty源码学习笔记之概念解读

    尊重原创,转载注明出处,原文地址:http://www.cnblogs.com/cishengchongyan/p/6121065.html  博主最近在做网络相关的项目,因此有契机学习netty,先 ...

  8. netty源码学习

    概述 Netty is an asynchronous event-driven network application framework for rapid development of main ...

  9. Netty源码学习系列之1-netty的串行无锁化

    前言 最近趁着跟老东家提离职之后.到新公司报道之前的这段空闲时期,着力研究了一番netty框架,对其有了一些浅薄的认识,后续的几篇文章会以netty为主,将近期所学记录一二,也争取能帮未对netty有 ...

随机推荐

  1. 【BZOJ1059】【ZJOI2007】矩阵游戏

    Description 小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏――矩阵游戏.矩阵游戏在一个N*N黑白方阵进行(如同国际象棋一般,只是颜色是随意的).每次可以对该矩阵进行两 ...

  2. ●BZOJ 3527 [Zjoi2014]力

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3527 题解: FFT求卷积. $$\begin{aligned}E_i&=\frac ...

  3. [USACO 5.1.3]乐曲主题

    Description 我们用N(1 <= N <=5000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,每个数表示钢琴上的一个键.很不幸这种表示旋律的方法忽略了音符的 ...

  4. [BZOJ]1052 覆盖问题(HAOI2007)

    三矩形覆盖问题啊……不过听说FJOI还出过双圆覆盖问题? Description 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来, ...

  5. 基于Mapxtreme for JAVA的电子地图设计与实现

    基于Mapxtreme for JAVA的电子地图设计与实现学生毕业设计,适合测绘类专业研究目标:        开发一个基于MapXtreme for JAVA的校园电子地图项目,使用MapInfo ...

  6. Centos7发送邮件

    Centos7发送邮件 $ yum -y install mailx sendmail $ vim /etc/mail.rc set from=xxxxxx@.com set smtp=smtp..c ...

  7. C语言程序设计第四次作业——选择结构(二)

    (一)改错题 错误信息: 错误原因:第13行sqrt数学函数缺少")",导致编译器无法将括号正确配对 改正方法:补齐缺少的")" 错误信息: 错误原因:if语句 ...

  8. 批量录入快递地址-快宝地址服务(PHP代码示例)

    快递地址写错了怎么办?快递地址写的不详细怎么办?怎么皮批量录入收件人地址?微商怎么批量录入发件人地址?快宝地址清洗,有效的解决了寄送快递时,批量录入收件人信息.发件人信息时,纠正地址数据,不完整地址识 ...

  9. Python学习---字符串处理

    This world is but a canvas to our imagination. 世界只是我们的想象的画布. ----Apri 22 ''' 题目内容: "Pig Latin&q ...

  10. Go 语言指向指针的指针

    如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量. 当定义一个指向指针的指针变量时,第一个指针存放第二个指针的地址,第二个指针存放变量的地址: 指向指针的指针变量声 ...