3.0 Channel

2017-02-05 09:36:07 9,159 1

Netty中通道是对java原生网络编程api的封装,其顶级接口是Channel。

以TCP编程为例 ,在java中,有两种方式:

  1. 基于BIO,JDK1.4之前,我们通常使用java.net包中的ServerSocketSocket来代表服务端和客户端。

  2. 基于NIO,Jdk1.4引入nio编程之后,我们使用java.nio.channels包中的ServerSocketChannelSocketChannel来代表服务端与客户端。

在Netty中,对java中的BIO、NIO编程api都进行了封装,分别:

  1. 使用了OioServerSocketChannelOioSocketChannel对java.net包中的ServerSocket与Socket进行了封装

  2. 使用NioServerSocketChannelNioSocketChannel对java.nio.channels包中的ServerSocketChannel和SocketChannel进行了封装。

Netty中TCP编程的Channel类图继承关系如下:

Image.png

很容易可以看出,图中左半部分与右半部分是相互对应的:

  左半部分代表的是客户端:都实现了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都是其子类

Image.png

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;
...
}


上一篇:2.0 Netty入门案例 下一篇:3.1 ChannelConfig