传输API
每个Chnnel都会被分配一个ChannelPipeline和ChannelConfig。
由于Channel是独一无二的,所以为了保证顺序将Channel声明为java.lang.Compare的一个子接口。因此,如果两个不同的Channel实例都返回了相同的散列码,那么AbstractChannel中的compareTe()方法的实现将会抛出一个Error。
ChannelPipeline持有将应用于入站和出站数据以及事件的ChannelHanlder实例,这些ChannelHandler实现了应用程序用于处理状态变化以及数据处理的逻辑。
ChannelHandler的典型用途包括:
- 将数据从一种格式转换为另一种格式
- 提供异常的通知
- 提供Channel变为活动或者非活动的通知;
- 提供当Channel注册到EventLoop或者从EventLoop注销时的通知;
- 提供有关用户自定义事件的通知。
Channel的方法
方法名 | 描述 |
---|---|
eventLoop | 返回分配给Channel的EventLoop |
pipeLine | 返回分配给Channel的ChannelPipeline |
isActive | 如果Channel是活动的,返回true |
localAddress | 返回本地的SocketAddress |
remoteAddress | 返回远程的ScoketAddress |
write | 将数据写到远程节点,这个数据将被传递给ChannelPipeline,并且排队直到它被冲刷 |
flush | 将之前已写的数据立即冲刷到底层,进行传输,如一个socket |
writeAndFlush | 等同于两个方法的复合 |
Netty的Channel实现是线程安全的,因此可以在多线程情况下将数据存储到同一个Channel。
NIO——非阻塞I/O
NIO提供了一个所有I/O操作的全异步的实现。他利用了自NIO子系统被引入JDK1.4时便可以用的基于选择器的API。
选择器背后的基本概念是充当一个注册表,在那里可以将请求在Channel的状态变化发生变化时得到通知。可能的状态变化有:
- 新的Channel已被接受并且就绪;
- Channel连接已经完成;
- Channel有已经就绪的可供读取的数据;
- Channel可用于写数据。
选择器运行在一个检查状态变化并对其做出响应的线程上,在应用程序状态的改变做出响应后,选择器会被重置,然后重复这个过程。
选择操作的位模式
名称 | 描述 |
---|---|
OP_ACCEPT | 请求在接受新连接并创建Channel时获得通知 |
OP_CONNECT | 请求在建立一个连接时获得通知 |
OP_READ | 请求当数据已经就绪,可以从Channel中读取时获取通知 |
OP_WRITE | 请求当可以向Channel中写更多的数据时获得通知。这处理了套接字缓冲区被完全填满的情况,这种情况通常发生在数据的发送速度大于远程节点的接收数据速度 |
对于所有Netty的传输实现都公有的级别API完全地隐藏了这些NIO的内部细节。
零拷贝
零拷贝是一种目前只有在使用NIO和Epoll传输时候才可以使用的特性。它快速高效地将数据从文件系统移动到网络接口,而不需要将其从内核空间复制到用户空间,像在FTP或者HTTP这样的协议中可以显著地提升性能。但是,并不是所有的操作系统都支持这个特性。特别,他对于实现了数据加密或者压缩的文件系统都不可用——只能传输文件的原始内容。