Java NIO之SocketChannel

来源:互联网 发布:手机身份证ocr识别软件 编辑:程序博客网 时间:2024/04/30 17:07

SocketChannel类

简介

该类针对面向流的连接套接字的可选择通道。

套接字通道不是连接网络套接字的完整抽象。必须通过调用 socket 方法所获得的关联 Socket 对象来完成对套接字选项的绑定、关闭和操作。不可能为任意的已有套接字创建通道,也不可能指定与套接字通道关联的套接字所使用的 SocketImpl 对象。

通过调用此类的某个 open 方法创建套接字通道。新创建的套接字通道已打开,但尚未连接。试图在未连接的通道上调用 I/O 操作将导致抛出 NotYetConnectedException。可通过调用套接字通道的 connect 方法连接该通道;一旦连接后,关闭套接字通道之前它会一直保持已连接状态。可通过调用套接字通道的 isConnected 方法来确定套接字通道是否已连接。

套接字通道支持非阻塞连接:可创建一个套接字通道,并且通过 connect 方法可以发起到远程套接字的连接,之后通过 finishConnect 方法完成该连接。可通过调用 isConnectionPending 方法来确定是否正在进行连接操作。

可单独地关闭 套接字通道的输入端和输出端,而无需实际关闭该通道。调用关联套接字对象的 shutdownInput 方法来关闭某个通道的输入端将导致该通道上的后续读取操作返回 -1(指示流的末尾)。调用关联套接字对象的 shutdownOutput 方法来关闭通道的输出端将导致该通道上的后续写入操作抛出 ClosedChannelException。

套接字通道支持异步关闭,这与 Channel 类中所指定的异步 close 操作类似。如果一个线程关闭了某个套接字的输入端,而同时另一个线程被阻塞在该套接字通道上的读取操作中,那么处于阻塞线程中的读取操作将完成,而不读取任何字节且返回 -1。I如果一个线程关闭了某个套接字的输出端,而同时另一个线程被阻塞在该套接字通道上的写入操作中,那么阻塞线程将收到 AsynchronousCloseException。

多个并发线程可安全地使用套接字通道。尽管在任意给定时刻最多只能有一个线程进行读取和写入操作,但数据报通道支持并发的读写。connect 和 finishConnect 方法是相互同步的,如果正在调用其中某个方法的同时试图发起读取或写入操作,则在该调用完成之前该操作被阻塞。 代码声明为:

public abstract class SocketChannelextends AbstractSelectableChannelimplements ByteChannel, ScatteringByteChannel, GatheringByteChannel

构造方法

protected SocketChannel(SelectorProvider provider)初始化此类的一个新实例。

常用方法

public static SocketChannel open()                          throws IOException打开套接字通道。 通过调用系统级默认 SelectorProvider 对象的 openSocketChannel 方法来创建新的通道。 返回:新的套接字通道 抛出: IOException - 如果发生 I/O 错误
public final int validOps()返回一个操作集,标识此通道所支持的操作。 套接字通道支持连接、读取和写入,所以此方法返回 (SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE)。 指定者:类 SelectableChannel 中的 validOps返回:有效操作集
public abstract Socket socket()获取与此通道关联的套接字。 返回的对象不会声明任何在 Socket 类中未声明的公共方法。 返回:与此通道关联的套接字
public abstract int read(ByteBuffer dst)                  throws IOException                  将字节序列从此通道中读入给定的缓冲区。 尝试最多从该通道中读取 r 个字节,其中 r 是调用此方法时缓冲区中剩余的字节数,即 dst.remaining()。 假定读取的字节序列长度为 n,其中 0 <= n <= r。此字节序列将被传输到缓冲区中,序列中的第一个字节位于索引 p 处,最后一个字节则位于索引 p + n - 1 处,其中 p 是调用此方法时缓冲区的位置。返回时,该缓冲区的位置将等于 p + n;其限制不会更改。 读取操作可能不填充缓冲区,实际上它可能根本不读取任何字节。是否如此执行取决于通道的性质和状态。例如,处于非阻塞模式的套接字通道只能从该套接字的输入缓冲区中读取立即可用的字节;类似地,文件通道只能读取文件中剩余的字节。但是可以保证,如果某个通道处于阻塞模式,并且缓冲区中至少剩余一个字节,则在读取至少一个字节之前将阻塞此方法。 可在任意时间调用此方法。但是如果另一个线程已经在此通道上发起了一个读取操作,则在该操作完成前此方法的调用被阻塞。 指定者:接口 ReadableByteChannel 中的 read参数:dst - 要向其中传输字节的缓冲区 返回:读取的字节数,可能为零,如果该通道已到达流的末尾,则返回 -1 抛出: NotYetConnectedException - 如果尚未连接此通道 ClosedChannelException - 如果此通道已关闭 AsynchronousCloseException - 如果正在进行读取操作时另一个线程关闭了此通道 ClosedByInterruptException - 如果正在进行读取操作时另一个线程中断了当前线程,因此关闭了该通道并将当前线程设置为中断状态 IOException - 如果发生其他 I/O 错误
public abstract int write(ByteBuffer src)                   throws IOException                   将字节序列从给定的缓冲区中写入此通道。 尝试最多向该通道中写入 r 个字节,其中 r 是调用此方法时缓冲区中剩余的字节数,即 src.remaining()。 假定写入长度为 n 的字节序列,其中 0 <= n <= r。从缓冲区的索引 p 处开始传输该字节,其中 p 是调用此方法时该缓冲区的位置;最后写入的字节索引是 p + n - 1。返回时,该缓冲区的位置将等于 p + n;其限制不会更改。 除非另行指定,否则仅在写入所有请求的 r 个字节后 write 操作才会返回。有些类型的通道(取决于它们的状态)可能仅写入某些字节或者可能根本不写入。例如,处于非阻塞模式的套接字通道只能写入该套接字输出缓冲区中的字节。 可在任意时间调用此方法。但是如果另一个线程已经在此通道上发起了一个写入操作,则在该操作完成前此方法的调用被阻塞。 指定者:接口 WritableByteChannel 中的 write参数:src - 要从中获取字节的缓冲区 返回:写入的字节数,可能为零 抛出: NotYetConnectedException - 如果尚未连接此通道 ClosedChannelException - 如果此通道已关闭 AsynchronousCloseException - 如果正在进行写入操作时另一个线程关闭了此通道 ClosedByInterruptException - 如果正在进行写入操作时另一个线程中断了当前线程,因此关闭了该通道并将当前线程的状态设置为中断 IOException - 如果发生其他 I/O 错误
0 0