开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第24天,点击查看活动详情
public class NettyServer {
public static void main(String[] args) {
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
protected void initChannel(NioSocketChannel ch) {
}
});
serverBootstrap.bind(8000);
}
}
来看这样一段代码。
boosGroup是用来监听accept新连接的线程组,workGrop是用来处理新连接的线程组。
引导类 ServerBootstrap,这个类将引导我们进行服务端的启动工作,直接new出来开搞
通过group注册上面2个Group类
channel则是指定IO模型
需要线程模型(boosGroup,workersGroup)、IO 模型(NioServerSocketChannel),以及 IO 业务处理逻辑(initChannel方法中的逻辑)三大参数
客户端启动流程
public class NettyClient {
public static void main(String[] args) {
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap
// 1.指定线程模型
.group(workerGroup)
// 2.指定 IO 类型为 NIO
.channel(NioSocketChannel.class)
// 3.IO 处理逻辑
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
}
});
// 4.建立连接
bootstrap.connect("juejin.cn", 80).addListener(future -> {
if (future.isSuccess()) {
System.out.println("连接成功!");
} else {
System.err.println("连接失败!");
}
});
}
}
差不多,也是需要线程模型(boosGroup,workersGroup)、IO 模型(NioServerSocketChannel),以及 IO 业务处理逻辑(initChannel方法中的逻辑)三大参数
客户端和服务端实现双向通信
建立连接的话需要重写channelActive方法,回复消息的话需要重写channelRead方法
具体代码实现可看demo
数据传输载体ByteBuffer介绍
感觉跟计算机网络的滑动窗口有点像
读字节时读指针向右移动一格,写字节时写指针向右移动一格,还会维护capacity,如果写指针写道capacity时,就不能再写了,而是需要先判断capacity是否小于maxCapacity,小于的话就先进行扩容
API
上面2个代码的作用是一样的,都是可以在进行一些读操作后进行反复读取,推荐方式2,方式1会自己定义变量,不太友好,写操作也是一样的,那么在我们进行了上述的操作后,就可以对一些数据进行反复读取了
Netty使用到的内存需要我们手动回收
release() 与 retain()
原理跟可重入锁差不多,当创建完一个 ByteBuf,它的引用为1,调用一次retain(),引用+1,调用一次release(),引用-1,当引用为0时,自动回收