NIO学习笔记(三)---通道

1、通道基础

    通道(channel)用于在字节缓冲区和位于通道另一侧的实体(通常是一个文件或者套接字)之间有效的传输数据。通道将数据传输给ByteBuffer对象或者从ByteBuffer对象获取数据进行传输。

    通道是一种途径,借助该途径,可以用最小的总开销来访问操作系统本身的I/O服务。缓冲区则是通过内部用来发送和接受数据的端点。

    通道是访问I/O服务的导管,I/O可以分为广义的两大类别:File  I/O和Stream I/O。那么相应的有两种类型的通道也就不足为奇了,他们是文件(File)通道和套接字(socket)通道。

    通道会连接一个特定I/O服务且通道实例(channel instance)的性能受它所连接的I/O服务的特征限制

    通道可以以阻塞(blocking)或非阻塞(noblocking)模式运行。非阻塞模式的通道永远不会让调用的县城休眠。请求的操作要么立即完成,要么返回一个结果表明未进行任何操作。只有面向流的(stream-oriented)的通道,如sockets和pipes才能使用非阻塞模式。

2、Scatter/Gather

    通道提供了一种被称为Scatter/Gather的重要新功能(有时也被称为矢量I/O)。Scatter/Gather是一个简单却强大的概念,它是指在多个缓冲区上实现一个简单的I/O操作。对于一个write操作而言,数据时从几个缓冲区按照顺序抽取(称为gather)并沿着通道发送的。缓冲区本身不需要具备这种gather的能力。该gather过程的效果就好比全部缓冲区得内容被连接起来,并在发送数据前存放到一个大的缓冲区中。对于read操作而言,从通道读取的数据会按顺序被散步(称为Scatter)到多个缓冲区,将每个缓冲区填满直至通道中的数据或者缓冲区的最大空间被消耗完。

    很简单的,我们可以用一个gather操作将多个缓冲区的数据组合并发送出去。使用相同的缓冲区,我们可以像下面这样汇总数据并在一个socket通道上发送包。使用Scatter则刚好相反。

    使用得当的话,Scatter/Gather会是一个及其强大的工具。它允许用户您委托操作系统来完成辛苦活:将读取到的数据分开存放到多个存储桶(bucket)或者将不同的数据区合并成一个整体。

3、文件通道

    此处省略一万字。。。。。。

4、socket通道

    DatagramChannel和SocketChannel实现定义读写功能的接口,而ServerSocketChannel不实现。ServerSocketChanel负责监听传入的连接和创建新的SocketChannel对象,它本身不传输数据。

   1> ServerSocketChannel是一个基于通道的socket监听器。它同我们所熟悉的java.net.ServerSocket执行相同的基本任务,不过它增加了通道语义,因此能够在非阻塞模式下运行。

    用静态的open()工厂方法创建一个新的ServerSocketChannel对象,将会返回同一个未绑定的java.net.ServerSocket关联的通道。该对等ServerSocket可以通过在返回的ServerSocketChannel上调用socket()方法来获取。作为serverSocketChannel的对等体被创建的ServerSocket对象依赖通道实现。这些socket关联的SocketImpl能识别通道。通道不能被封装在随意的socket对象外面。

    2>Socket和SocketChannel类封装点对点、有序的网络连接,类似于我们所熟知并喜爱的TCP/IP网络连接。SocketChannel扮演客户端发起同一个监听服务器的连接。指导连接成功,它才能收到数据并且只会从连接到的地址接受。每个SocketChannel对象创建时都是同一个对等的java.net.Socket对象串联的。静态的open()方法可以创建一个新的SocketChannel对象,而在新创建的SocketChannel上调用socket()方法能返回它对等的Socket对象;在该socket上调用getChannel()方法则能返回最初的那个SocketChannel。

    3>最后一个socket通道是DatagramChannel。正如SocketChannel对应socket,serverSocketChannel对应serverSocket,每一个DatagramChannel对象也有一个关联的DatagramSocket对象。

    正如socketChannel模拟连接导向的流协议(如TCP/IP),DatagramChannel则模拟包导向的无连接协议(如UDP/IP)。创建DatagramChannel的模式和创建其他Socket通道是一样的。DatagramChannel对象既可以充当服务器(监听者)也可以充当客户端(发送者)。如果您希望新创建的通道负责监听,那么通道必须首先被绑定到一个端口或者地址、端口组合上。绑定DatagramChannel同时绑定一个常规的DategramSocket没什么区别。

    DatagramChannel是无连接的。每个数据报(datagram)都是一个自包含的实体,拥有它自己的目的地址及不依赖其他数据报的数据净荷。与面向流的的socket不同,DatagramChannel可以发送单独的数据报给不同的目的地址。同样,DatagramChannel对象也可以接收来自任意地址的数据包。每个到达的数据报都含有关于它来自何处的信息(源地址)。

5、管道

    管道(pipe)就是一个用来在两个实体之间单向传输数据的导管。在Unix系统中,管道被用来连接一个进程的输出和另一个进程的输入。管道可以被用来尽在同一个java虚拟机内部传输数据。虽然有更加有效率的方式来在线程之间传输数据,但是使用管道的好处在于封装性。

猜你喜欢

转载自freewxy.iteye.com/blog/949395
今日推荐