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

NIO:流(TCP)信道详解

 
阅读更多

流信道有两个变体:SocketChannelServerSocketChannel。像其对应的Socket一样,SocketChannel是相互连接的终端进行通信的信道。

SocketChannel:创建,连接和关闭

static SocketChannel open(SocketAddress remote)

static SocketChannel open()

boolean connect(SocketAddress remote)

boolean isConnected()

void close()

boolean isOpen()

Socket socket()

调用SocketChannel的静态工厂方法open()可以创建一个实例。open()方法的第一种形式SocketAddress(见第2章)为参数,返回一个连接到指定服务器的SocketChannel实例。注意,该方法可能会无限期地阻塞下去。open()的无参数形式用于创建一个没有连接的SocketChannel实例,该实例可以通过调用connect()方法连接到指定终端。当使用完SocketChannel后,需要调用close()方法将其关闭。有一点很重要,即每个SocketChannel实例都"包裹"了一个基本Java Socket,并可以通过socket()方法对该Socket进行访问。这就可以通过基本的Socket方法进行绑定、设置套接字选项等操作。一个SocketChannel的创建、连接和关闭的例子,见TCPEchoClientNonblocking.java(第113-114页)。

在创建并连接SocketChannel后,就可以调用该信道的读写方法进行I/O操作。

SocketChannel:读和写

int read(ByteBuffer dst)

long read(ByteBuffer[] dsts)

long read(ByteBuffer[] dsts, int offset, int length)

int write(ByteBuffer src)

long write(ByteBuffer[] srcs)

long write(ByteBuffer[] srcs, int offset, int length)

读操作的最基本形式以一个ByteBuffer为参数,并将读取的数据填入该缓冲区所有的剩余字节空间中。另一种形式以多个ByteBuffer为参数(ByteBuffer数组),并根据其在数组中的顺序,将读取的数据依次填入每个缓冲区的剩余字节空间中。这种方法称为散射式读,因为它将读入的字节分散到了多个缓冲区中。需要注意重要的一点,散射式读不一定会将所有缓冲区填满,这些缓冲区的总空间大小只是一个上限。

写操作的最基本形式以一个ByteBuffer为参数,并试图将该缓冲区中剩余的字节写入信道。另一种形式以一个ByteBuffer数组作为参数,并试图将所有缓冲区中的剩余字节都写入信道。这种方法称为聚集式写,因为它把多个缓冲区中的字节聚集起来,一起发送出去。读

写操作的例子见TCPEchoClientNonblocking.javaTCPServerSelector.java

与其对应的ServerSocket一样,ServerSocketChannel是用来侦听客户端连接的信道。

ServerSocketChannel:创建,接受和关闭

static ServerSocketChannel open()

ServerSocket socket()

SocketChannel accept()

void close()

boolean isOpen()

调用静态工厂方法open()可以创建一个ServerSocketChannel实例。每个实例都包裹了一ServerSocket实例,并可以通过socket()方法对其访问。正如前面的例子所表明的,必须通过访问底层的ServerSocket实例来实现绑定指定端口,设置套接字选项等操作。在创建了信道实例并绑定端口后,就可以调用accept()方法来准备接收客户端的连接请求。连接成功则返回一个新的已连接的SocketChannel。在用完ServerSocketChannel后,需要调用close()方法将其关闭。使用ServerSocket的例子见TCPServerSelector.java(第116-117页)。

如前文提到的那样,阻塞式信道除了能够(必须)与Buffer一起使用外,对于普通套接字来说几乎没有优点。因此,可能总是需要将信道设置成非阻塞式的。

SocketChannel, Server SocketChannel:设置阻塞行为

SelectableChannel configureBlocking(boolean block)

boolean isBlocking()

通过调用configureBlocking(false)可以将SocketChannelServerSocketChannel设置为非阻塞模式。configureBlocking()方法将返回一个SelectableChannel,它是SocketChannelServerSocketChannel父类。

考虑为SocketChannel设置连接的情况。如果传给SocketChannel的工厂方法open()一个远程地址,对该方法的调用则将阻塞等待,直到成功建立了连接。要避免这种情况,可以使open()方法的无参数形式,配置信道为非阻塞模式,再调用connect()方法,指定远程终端地址。如果在没有阻塞的情况下连接已经建立,connect()方法返回true;否则需要有检查套接字是否连接成功的方法。

SocketChannel:测试连接性

boolean finishConnect()

boolean isConnected()

boolean isConnectionPending()

对于非阻塞SocketChannel来说,一旦已经发起连接,底层套接字可能即不是已经连接,又不是没有连接,而是连接"正在进行"。由于底层协议的工作机制(见第6章),套接字可能会在这个状态一直保持下去。finishConnect()方法可以用来检查在非阻塞套接字上试图进行的连接的状态,还可以在阻塞套接字建立连接的过程中阻塞等待,直到连接成功建立。例如,你可能需要将信道配置成非阻塞模式,通过connect()方法发起连接,做完一些其他工作后,又将信道配置成阻塞模式,然后调用finishConnect()方法等待连接建立完成。或者可以让信道保持在非阻塞模式,并反复调用finishConnect()方法,如TCPEchoClientNonblocking.java中所示。

isConnected()用于检查套接字是否已经建立了连接,从而避免在进行其他操作时抛出NotYetConnectedException异常(如调在用read()write()时)。还可以使用isConnectionPending()方法来检查是否有连接在该信道上发起。知道是否有连接发起是必要的,因为如果没有的话,finishConnect()方法将抛出NoConnectionPendingException异常。

相关下载:

Java_TCPIP_Socket编程(doc)

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

文献来源:

LSOFT.CN(琅软中国)

分享到:
评论

相关推荐

    一站式学习Java网络编程 全面理解BIO:NIO:AIO1

    一站式学习Java网络编程 全面理解BIO:NIO:AIO1

    httpcore-nio-4.4.6-API文档-中英对照版.zip

    Maven坐标:org.apache.httpcomponents:httpcore-nio:4.4.6; 标签:apache、httpcomponents、nio、httpcore、jar包、java、中英对照文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可...

    tcp.zip_java Tcp _java nio_java nio TCP_tcp_tcp java

    TCP NIO socket TCP服务器,支持多个客户端连接

    httpcore-nio-4.4.14-API文档-中文版.zip

    Maven坐标:org.apache.httpcomponents:httpcore-nio:4.4.14; 标签:apache、httpcomponents、httpcore、nio、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览...

    Servlet API 和 NIO: 最终组合在一起

    NULL 博文链接:https://conkeyn.iteye.com/blog/523234

    java NIO 视频教程

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

    java_Netty权威指南,详解nio,tcp,http,netty

    java_Netty权威指南,详解nio,tcp,http,netty.rar

    java nio教程pdf

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

    postgres-nio::elephant:用于PostgreSQL非阻塞,事件驱动的Swift客户端

    postgres-nio::elephant:用于PostgreSQL非阻塞,事件驱动的Swift客户端

    JavaNIO_API帮助文档详解

    JavaNIO_API帮助文档详解,对于开发NIO很有帮助

    mqtt-nio:Swift NIO MQTT 3.1.1客户端

    MQTT NIO 一个基于Swift NIO的MQTT 3.1.1客户端,通过NIOSSL和NIOTransportServices支持NIOTransportServices(iOS必需),WebSocket连接和TLS。 MQTT(消息队列遥测传输)是IBM开发的轻量级消息协议,于1999年...

    nio:用于Nim语言的迷你服务器框架

    nio:用于Nim语言的迷你服务器框架

    xnio-nio-3.8.4.Final-API文档-中文版.zip

    Maven坐标:org.jboss.xnio:xnio-nio:3.8.4.Final; 标签:jboss、xnio、nio、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的...

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

    面向流(Stream Oriented) 面向缓冲区(Buffer Oriented) 阻塞IO(Blocking IO) 非阻塞IO(NonBlocking IO) (无) 选择器(Selectors) 2. NIO_缓冲区(Buffer)的数据存取 缓冲区(Buffer):在 Java NIO 中负责...

    nio:Clojure对java.nio的支持

    将clojure.java.io的输入流,输出流和复制功能扩展到java.nio类。 定义新的强制功能缓冲区,字节缓冲区,字符缓冲区,双缓冲区,浮点缓冲区,整数缓冲区,长缓冲区,短缓冲区,通道,可读通道和可写通道。 这些功能...

    Java NIO详解及源码下载

    博客地址:http://blog.csdn.net/u010156024/article/details/44310709 欢迎访问。 代码中详细讲述了Java io流和nio流的用法,可以参考学习。

    nio:Go #golang中的并发缓冲IO

    ReadWriter} nio的Copy方法同时从io.Reader复制到提供的nio.Buffer,然后从nio.Buffer复制到io.Writer。 这样,阻止写入不会降低io.Reader的速度。 import ( "github....

    nio:o Nio是即将推出的iOS矩阵客户端

    :speech_balloon: o Nio是即将推出的iOS 客户端。 目前,该项目仍在进行中。 有关更新,请在我们的矩阵房→ 。 想试一试吗? 加入公共 。入门由于仁王使用斯威夫特软件包管理器,所有你需要做的是克隆的项目,在...

    httpcore-nio-4.4.5-API文档-中文版.zip

    Maven坐标:org.apache.httpcomponents:httpcore-nio:4.4.5; 标签:apache、httpcomponents、nio、httpcore、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览...

    yubo-java-nio:java nio的学习项目

    yubo-java-nioNIO 直接缓冲区 VS 非直接缓冲区直接缓冲区1、直接缓冲区最适合I/O 2、创建成本比非直接缓冲区高 3、直接缓冲区使用的内存是通过调用原生的、操作系统特定的代码来分配的 4、内存存储区域不受限制垃圾...

Global site tag (gtag.js) - Google Analytics