netty(七)--Bootstrap

本文详细介绍了Netty中引导客户端和服务器的过程,包括Bootstrap和ServerBootstrap类的使用,以及如何设置EventLoopGroup、Channel、ChannelHandler等关键组件。同时,还讲解了如何处理无连接协议的DatagramChannel。

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

引导一个应用程序是指对它进行配置,并使他运行起来的过程。
在这里插入图片描述
服务器致力于使用一个父 Channel 来接受
来自客户端的连接, 并创建子 Channel 以用于它们之间的通信;而客户端将最可能只需要一个
单独的、 没有父 Channel 的 Channel 来用于所有的网络交互。


bootstrap类的API

名称描述
Bootstrap group(EventLoopGroup g)设置用于处理channel所有事件的eventLoop
Bootstrap channel(class),Bootstrap channelFactory指定channel的实现类,或者工厂类作为参数
Bootstrap localAddress(socketaddress)指定channel应该绑定的本地地址。指定channel应该绑定到的地址,如果没有指定,将由操作系统创建一个随机的地址。或者,也可以通过bind()或者connect方法指定localAddress
Bootstrap option(channelOption,T)设置channelOption,其将被应用到每个新创建的channel的channelConfig。这些选项将会通过bind或者connect方法设置到channel。这个方法对于已经被创建的线程无效
Bootstrap attr(key,val)指定新创建的channel属性值,作用同上
Bootstrap handler(ChannelHandler)设置将被添加到ChannelPipeline以接收事件通知的channelHandler
Bootstrap clone()创建一个Boostrap的克隆,具有和原始bootstrap相同的设置信息
Boostrap remoteAddress设置远程地址,或者通过connect方法指定
channelFuture connect()连接到远程节点并返回一个channelFuture,其将会在连接操作完成后接到通知
channelFuture bind()绑定channel并返回一个channelFuture,其将会在绑定操作完成后接收到通知,在那之后必须调用channel,connect方法来建立连接。
引导客户端

bootstrap类负责为客户端和使用无连接协议的应用程序创建channel。
在这里插入图片描述

channel和EventLoopGroup的兼容性

在这里插入图片描述
不能混用具有不同前缀的组件。
在引导的过程中,在调用 bind()或者 connect()方法之前,必须调用以下方法来设置所需的组件:

  • group();
  • channel()或者 channelFactory();
  • handler()。

如果不这样做, 则将会导致 IllegalStateException。对 handler()方法的调用尤其重要,因为它需要配置好 ChannelPipeline。

引导服务器

ServerBootstrap类的方法

名称描述
group设置serverBootstrap要用的EventLoopGroup。这个EventLoopGroup将用于ServerChannel和被接受的子Channel的I/O处理
channel设置将要被实例化的ServerChannel类
channelFactory如果不能通过默认的构造函数创建Channel,可以提供一个ChannelFactory
localAddress指定serverchannel应该绑定到的本地地址,如果没有指定,则将由操作系统使用一个随即地址,或者通过bind方法来指定改localAddress
option指定要应用到新创建的 ServerChannel 的 ChannelConfig 的 ChannelOption。 这些选项将会通过 bind()方法设置到 Channel。在 bind()方法被调用之后, 设置或者改变 ChannelOption 都不会有任何的效果。所支持的 ChannelOption 取决于所使用的 Channel 类型。
childOption指定当子channel被接受时,应用到子Channel的ChannelConfig的channelOption。
attr指定serverChannel的属性,属性将通过bind方法设置给channel
childAttr将属性设置给已经被接受的子channel
handler设置被添加到serverChannel的channelPipeline中的channelHandler
childHandler设置将被添加到的已被接受的子channel的channelpipeline中的channelhandler。
bind绑定serverChannel并且返回一个ChannelFuture,其将在绑定操作完成后收到通知

ServerChannel 的实现负责创建子 Channel,这些子 Channel 代表了已被接受的连接。
在这里插入图片描述


假设你的服务器正在处理一个客户端的请求, 这个请求需要它充当第三方系统的客户端。当一个应用程序(如一个代理服务器)必须要和组织现有的系统(如 Web 服务或者数据库)集成时,就可能发生这种情况。 在这种情况下,将需要从已经被接受的子 Channel 中引导一个客户端 Channel。
在这里插入图片描述

ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.childHandler(
new SimpleChannelInboundHandler<ByteBuf>() {
ChannelFuture connectFuture;
@Override
public void channelActive(ChannelHandlerContext ctx)
throws Exception {
Bootstrap bootstrap = new Bootstrap();
bootstrap.channel(NioSocketChannel.class).handler(
new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(
ChannelHandlerContext ctx, ByteBuf in)
throws Exception {
System.out.println("Received data");
}
} );
bootstrap.group(ctx.channel().eventLoop());
connectFuture = bootstrap.connect(
new InetSocketAddress("www.manning.com", 80));
}
@Override
protected void channelRead0(
ChannelHandlerContext channelHandlerContext,
ByteBuf byteBuf) throws Exception {
if (connectFuture.isDone()) {
// do something with the data
}
}
} );
ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080));
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture)
throws Exception {
if (channelFuture.isSuccess()) {
System.out.println("Server bound");
} else {
System.err.println("Bind attempt failed");
channelFuture.cause().printStackTrace();
}
}
} );

在引导过程中添加多个 ChannelHandler,使用自定义的ChannelInitializer。

protected void initChannel(Channel ch) throws Exception {
	ChannelPipeline pipeline = ch.pipeline();
	pipeline.addLast(new HttpClientCodec());
}
DatagramChannel

前面的引导都是基于TCP协议的SocketChannel,对于无连接的协议,netty提供了各种DatagramChannel的实现。

 public void serve(){
        Bootstrap bootstrap=new Bootstrap();
        bootstrap.group(new OioEventLoopGroup())
                .channel(OioDatagramChannel.class)
                .handler(new SimpleChannelInboundHandler<DatagramPacket>() {
                    @Override
                    protected void channelRead0(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket) throws Exception {

                    }
                });
        ChannelFuture future=bootstrap.bind(new InetSocketAddress(0));//该协议是无连接的
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                if (channelFuture.isSuccess()){
                    System.out.println("channel bind");
                }else {
                    System.out.println("channel bind failed");
                    channelFuture.cause().printStackTrace();
                }
            }
        });
    }

调用 EventLoopGroup.shutdownGracefully()方法关闭 EventLoopGroup, 它将处理任何挂起的事件和任务,并且随后
释放所有活动的线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值