【超详细解释】从Java NIO到Netty的每一步 (一)

前言

由于我之前接触的架构(Vert.x)或者中间件(Dubbo、RocketMQ)底层均基于Netty实现,再加上Netty越来越受到青睐,所以想学习一下Netty。
又因为看源码发现很多概念和实现都是基于Java NIO的,所以还是需要先学习一下Java NIO基础知识。所以学习的思路变为Java NIO -> Netty基本概念 ->Netty源码。
如果有什么不对或者不清楚的地方,欢迎大家一起讨论。

Java NIO组件介绍

Channel

Channel 有点象流。 数据可以从Channel读到Buffer中,也可以从Buffer写到Channel中。这里有个图示:

下面是JAVA NIO中的一些主要Channel的实现:

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel
    接下来我们主要讲SocketChannelServerSocketChannel

ServerSocketChannel

ServerSocketChannel 是一个可以监听新进来的TCP连接的通道,就像标准IO中的ServerSocket一样。

代码样例:

//打开ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//监听端口9999
serverSocketChannel.socket().bind(new InetSocketAddress(9999));
//设置为非阻塞模式
serverSocketChannel.configureBlocking(false);
while(true){
    //设置为非阻塞模式会导致accept方法立即返回,所以可能返回null
    SocketChannel socketChannel =
            serverSocketChannel.accept();
    //do something with socketChannel...
}

SocketChannel

SocketChannel是一个连接到TCP网络套接字的通道。如1.1中,当一个连接到达时可以创建一个SocketChannel。

  1. 将SocketChannel的数据读到buffer中:
ByteBuffer buf = ByteBuffer.allocate(2048);
int bytesRead = socketChannel.read(buf);

read()方法返回的int值表示读了多少字节进Buffer里。如果返回的是-1,表示已经读到了流的末尾(连接已经关闭)。

  1. 将buffer的数据写入SocketChannel
String newData = "hello world";
//Buffer操作后面章节介绍
ByteBuffer buf = ByteBuffer.allocate(2048);
buf.clear();
buf.put(newData.getBytes());
buf.flip();
while(buf.hasRemaining()) {
    channel.write(buf);
}

注意write()方法是放到while循环体里面的,因为没法保证一次write()会把多少字节写到SocketChannel里。

  1. 非阻塞模式
socketChannel.configureBlocking(false);

write():在非阻塞模式下,write()方法在尚未写出任何内容时可能就返回了。
read():在非阻塞模式下,read()方法在尚未读取到任何数据时可能就返回了。
非阻塞模式适合与Selector搭配使用,通过将一或多个SocketChannel注册到Selector,可以询问Selector哪个Channal已经准备好了读取,写入等,所以接下来介绍一下Selector。

关注我日常更新分享Java编程技术!希望大家都能早日走上人生巅峰!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛战士从不脱下面具

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值