3.0 Channel
Netty中通道是对java原生网络编程api的封装,其顶级接口是Channel。
以TCP编程为例 ,在java中,有两种方式:
基于BIO,JDK1.4之前,我们通常使用java.net包中的
ServerSocket
和Socket
来代表服务端和客户端。基于NIO,Jdk1.4引入nio编程之后,我们使用java.nio.channels包中的
ServerSocketChannel
和SocketChannel
来代表服务端与客户端。
在Netty中,对java中的BIO、NIO编程api都进行了封装,分别:
使用了
OioServerSocketChannel
,OioSocketChannel
对java.net包中的ServerSocket与Socket进行了封装使用
NioServerSocketChannel
和NioSocketChannel
对java.nio.channels包中的ServerSocketChannel和SocketChannel进行了封装。
Netty中TCP编程的Channel类图继承关系如下:
很容易可以看出,图中左半部分与右半部分是相互对应的:
左半部分代表的是客户端:都实现了SocketChannel接口
右半部分代表的是服务端:都实现了ServerChannel
接口,这是一个标记接口。
特别需要注意的是,虽然Netty使用通道的概念,对java原生BIO、NIO编程api都进行了封装,但是通道的概念其实是在java 1.4之后引入nio编程才出现的,因此只有NioServerSocketChannel和NioSocketChannel才有对应的java通道,可以看到这二者都继承自AbstractNioChannel
,其维护了netty中的channel与java nio中channel的对应关系,并提供了javaChannel()
方法获取对应的java 中的channel:
public abstract class AbstractNioChannel extends AbstractChannel { ... private final SelectableChannel ch; ... protected SelectableChannel javaChannel() {//获取对应的java通道 return ch; } }
上述代码片段中SelectableChannel
是java nio中的类,我们前面提到nio包中的SocketChannel、ServerSocketChannel都是其子类
NioSocketChannel和NioServerSocketChannel对AbstractNioChannel的javaChannel()进行了覆写,如下:
io.netty.channel.socket.nio.NioServerSocketChannel#javaChannel
@Override protected ServerSocketChannel javaChannel() {//返回java.nio.channels.ServerSocketChannel return (ServerSocketChannel) super.javaChannel(); }
io.netty.channel.socket.nio.NioSocketChannel#javaChannel
@Override protected SocketChannel javaChannel() {//返回java.nio.channels.SocketChannel return (SocketChannel) super.javaChannel(); }
对于OioSocketChannel和OioServerSocketChannel,是直接继承自AbstractChannel,内部直接维护了对应的Socket和ServerSocket。
public class OioSocketChannel extends OioByteStreamChannel implements SocketChannel { ... private final Socket socket; .... }
public class OioServerSocketChannel extends AbstractOioMessageChannel implements ServerSocketChannel { ... final ServerSocket socket; ... }