`
lovnet
  • 浏览: 6709086 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

NIO:与 Buffer 一起使用 Channel

 
阅读更多

如前文所述,Channel实例代表了一个与设备的连接,通过它可以进行输入输出操作。实际上Channel的基本思想与我们见过的普通套接字非常相似。对于TCP协议,可以使用ServerSocketChannelSocketChannel。还有一些针对其他设备的其他类型信道(如,FileChannel),尽管我们在后文中不会再提及,这里介绍的大部分内容对于它们同样适用。信道(channel)和套接字(socket)之间的不同点之一,可能是信道通常要调用静态工厂方法来获取实例:

SocketChannel clntChan = SocketChannel.open();

ServerSocketChannel servChan =

ServerSocketChannel.open();

Channel使用的不是流,而是缓冲区来发送或读取数据。Buffer类或其任何子类的实例都可以看作是一个定长的Java基本数据类型元素序列。与流不同,缓冲区有固定的、有限的容量,并由内部(但可以被访问)状态记录了有多少数据放入或取出,就像是有限容量的队列一样。Buffer是一个抽象类,只能通过创建它的子类来获得Buffer实例,而每个子类都设计为用来容纳一种Java基本数据类型(boolean除外)。因此,这些实例分别为FloatBufferIntBuffer,或ByteBuffer,等等(ByteBuffer是这些实例中最灵活的,并将在后面很多例子中用到)。在channel中使用Buffer实例通常不是使用构造函数创建的,而是通过调用allocate()方法创建指定容量的Buffer实例,

ByteBuffer buffer = ByteBuffer.allocate(CAPACITY);

或通过包装一个已有的数组来创建:

ByteBuffer buffer = ByteBuffer.wrap(byteArray);

NIO的强大功能部分来自于channel的非阻塞特性。回顾前面介绍的内容可以知道,套接字的某些操作可能会无限期地阻塞。例如,对accept()方法的调用可能会因为等待一个客户端连接而阻塞;对read()方法的调用可能会因为没有数据可读而阻塞,直到连接的另一端传来新的数据。总的来说,创建/接收连接或读写数据等I/O调用,都可能无限期地阻塞等待,直到底层的网络实现发生了什么。慢速的、有损耗的网络,或仅仅是简单的网络故障都可能导致任意时间的延迟。然而不幸的是,在调用一个方法之前无法知道其是否会阻塞。NIOchannel抽象的一个重要特征就是可以通过配置它的阻塞行为,以实现非阻塞式的信道。

clntChan.configureBlocking(false);

在非阻塞式信道上调用一个方法总是会立即返回。这种调用的返回值指示了所请求的操作完成的程度。例如,在一个非阻塞式ServerSocketChannel上调用accept()方法,如果有连接请求在等待,则返回客户端SocketChannel,否则返回null。下面我们来创建一个非阻塞TCP回显客户端。可能阻塞的I/O操作包括建立连接,读和写。通过使用非阻塞式信道,这些操作都将立即返回。我们必须反复调用这些操作,直到所有I/O操作都成功完成。

TCPEchoClientNonblocking.java

0 import java.net.InetSocketAddress;

1 import java.net.SocketException;

2 import java.nio.ByteBuffer;

3 import java.nio.channels.SocketChannel;

4

5 public class TCPEchoClientNonblocking {

6

7 public static void main(String args[]) throws Exception

{

8

9 if ((args.length < 2) || (args.length > 3)) // Test for

correct # of args

10 throw new IllegalArgumentException("Parameter(s):

<Server> <Word> [<Port>]");

11

12 String server = args[0]; // Server name or IP address

13 // Convert input String to bytes using the default

charset

14 byte[] argument = args[1].getBytes();

15

16 int servPort = (args.length == 3) ?

Integer.parseInt(args[2]) : 7;

17

18 // Create channel and set to nonblocking

19 SocketChannel clntChan = SocketChannel.open();

20 clntChan.configureBlocking(false);

21

22 // Initiate connection to server and repeatedly poll

until complete

23 if (!clntChan.connect(new InetSocketAddress(server,

servPort))) {

24 while (!clntChan.finishConnect()) {

25 System.out.print("."); // Do something else

26 }

27 }

28 ByteBuffer writeBuf = ByteBuffer.wrap(argument);

29 ByteBuffer readBuf =

ByteBuffer.allocate(argument.length);

30 int totalBytesRcvd = 0; // Total bytes received so far

31 int bytesRcvd; // Bytes received in last read

32 while (totalBytesRcvd < argument.length) {

33 if (writeBuf.hasRemaining()) {

34 clntChan.write(writeBuf);

35 }

36 if ((bytesRcvd = clntChan.read(readBuf)) == -1) {

37 throw new SocketException("Connection closed

prematurely");

38 }

39 totalBytesRcvd += bytesRcvd;

40 System.out.print("."); // Do something else

41 }

42

43 System.out.println("Received: " + // convert to String

per default charset

44 new String(readBuf.array(), 0, totalBytesRcvd));

45 clntChan.close();

46 }

47 }

TCPEchoClientNonblocking.java

1.获取并转换参数:第9-16

2.创建非阻塞式SocketChannel:第19-20

3.连接服务器:第23-27

由于该套接字是非阻塞式的,因此对connect()方法的调用可能会在连接建立之前返回,如果在返回前已经成功建立了连接,则返回true,否则返回false。对于后一种情况,任何试图发送或接收数据的操作都将抛出NotYetConnectedException异常,因此,我们通过持续调finishConnect()方法来"轮询"连接状态,该方法在连接成功建立之前一直返回false。打印操作演示了在等待连接建立的过程中,程序还可以执行其他任务。不过,这种忙等的方法非常浪费系统资源,这里这样做只是为了演示该方法的使用。

4.创建读写缓冲区:第28-29

我们分别使用了两种方法来创建将要用来读写数据的ByteBuffer实例。一是通过包装包含了要发送数据的byte[]数组,另一个方法是调用allocate()方法,创建具有与前面byte[]组大小相同缓冲区的ByteBuffer实例。

5.反复循环直到发送和接收完所有字节:第32-41

只要输出缓冲区中还留有数据,就调用write()方法。对read()方法的调用不会阻塞等待,但是当没有数据可读时该方法将返回0。这里,打印语句再次举例说明了在等待通信完成的过程中,程序可以执行其他任务。

6.打印接收到的数据:第43-44

7.关闭信道:第45

与套接字类似,信道在完成其任务后也需要关闭。

相关下载:

Java_TCPIP_Socket编程(doc)

http://download.csdn.net/detail/undoner/4940239

文献来源:

UNDONER(小杰博客) :http://blog.csdn.net/undoner

LSOFT.CN(琅软中国) :http://www.lsoft.cn

分享到:
评论

相关推荐

    java NIO 视频教程

    标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。 Java NIO: Non-blocking IO(非阻塞IO) Java NIO...

    java nio教程pdf

    标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。 Java NIO: Asynchronous IO(异步IO) Java NIO可以...

    java8源码-nio:java8nio使用的总结

    java8 源码 nio java8 nio使用的总结 ...NIO_通道(Channel)的原理与获取 通道(Channel):用于源节点与目标节点的连接。在 Java NIO 中负责缓冲区中数据的传输。 Channel 本身不存储数据,因此需要配合缓冲区进

    NIO详细介绍channle,buffer,Selector

    主要介绍一些关于NIO 的基础知识,有浅到深

    Java性能优化之使用NIO提升性能(Buffer和Channel)

    在软件系统中,由于IO的速度要比内存慢...使用java.nio.charset.Charset作为字符集编码解码解决方案;增加通道(channel)对象,作为新的原始I/O抽象;支持锁和内存映射文件的文件访问接口;提供了基于Selector的异步网

    尚硅谷Java视频_NIO 视频教程

    尚硅谷_NIO_通道(Channel)的原理与获取 ·05. 尚硅谷_NIO_通道的数据传输与内存映射文件 ·06. 尚硅谷_NIO_分散读取与聚集写入 ·07. 尚硅谷_NIO_字符集 Charset ·08. 尚硅谷_NIO_阻塞与非阻塞 ·09. 尚硅谷_NIO_...

    Java NIO实战开发多人聊天室

    13-Java NIO-Buffer-基本使用.mp4 14-Java NIO-Buffer-三个属性和类型.mp4 17-Java NIO-Buffer-缓冲区分片.mp4 18-Java NIO-Buffer-只读缓冲区.mp4 19-Java NIO-Buffer-直接缓冲区.mp4 21-Java NIO-Selector-概述....

    java网络编程NIO视频教程

    01-Java NIO-课程简介.mp4 02-Java NIO-概述.mp4 03-Java NIO-Channel-概述.mp4 ...13-Java NIO-Buffer-基本使用.mp4 14-Java NIO-Buffer-三个属性和类型.mp4 15-Java NIO-Buffer-分配和读写数据.mp4

    JavaNIO chm帮助文档

    Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六) Selector Java NIO系列教程(七) ...

    NIO实现多用户聊天demo,通过demo深入理解NIO三大组件:buffer、channel、selector

    目录运行效果截图:源代码:Server端:Client端:使用时注意:(持续更新) 运行效果截图: 启动server端: 依次启动client1、client2、client3并输入相应昵称...import java.nio.channels.Channel; import java.nio.c

    Java IO, NIO and NIO.2(Apress,2015)

    Next, you'll learn about NIO's buffer, channel, selector, regular expression, charset, and formatter APIs. Finally, you'll discover NIO.2's offerings in terms of an improved file system interface, ...

    javasnmp源码-nio-learn:JavaNIO使用示例,NIO的使用,TCP,UDP的简单示例

    java snmp 源码 Java NIO java nio 简介 Java NIO(New IO)是用于Java(来自Java ...NIO提供了与原来IO ...NIO支持面向缓冲区的,基于通道的IO操作。...NIO将以更加高效的方式进行文件的读写操作。...Buffer的基本使用 通过allo

    java nio中文版

    java NIO是 java New IO 的简称,在 jdk1.4 里提供的新 api 。 Sun 官方标榜的特性如下: – 为所有的原始类型提供 (Buffer) 缓存支持。 – 字符集编码解码解决方案。 – Channel :一个新的原始 I/O 抽象。 – 支持...

    core-nio:nio底层实现原理(另外还有aio的功能)

    core-niojava nio 客户端和服务端交互实现主要通过长连接的方式进行数据交换,采用多路复用技术,同步非阻塞模式。主要有以下几个概念Channel(渠道,类似于高速公路可以处理很多线程io);Selector(选择器,可以...

    Java+NIO+中文版.pdf

    java nio作者倾力所写的简单易懂的NIO学习指南,让你顺利拿下NIO开发,包括了NIO中的Buffer,Channel,Selector的介绍,理论&代码都有,是你学习NIO的不二法宝~

    浅谈java中nio的使用方式

    NIO其核心概念包括Channel,Selector,SelectionKey,Buffer.

    JAVA的IO与NIO

    nio与io的区别 Channel Buffer 事件及nio的非阻塞读取

    Java NIO系列教程

    Java NIO系列教程 Java NIO Channel Buffer Selector SocketChannel

Global site tag (gtag.js) - Google Analytics