面向 Socket 连接的 Channel 类
概述
1、NIO 对非阻塞 Socket 操作支持的组件,封装 Socket 上封装一层,主要支持非阻塞的读写,同时改进传统的单向流 API,Channel 同时支持读写
(1)主要实现类:DatagramChannel、SocketChannel、ServerSocketChannel
(2)在被实例化时都会创建一个对等 Socket 对象
2、要把一个 Socket 通道置于非阻塞模式,要依赖所有 Socket 通道类的顶级类:SelectableChannel
(1)就绪选择(readiness selection):查询通道的机制,可以判断通道是否准备好执行一个目标操作,如读或写
(2)非阻塞 I/O 和可选择性是紧密相连的,所以管理阻塞模式的 API 代码要在 SelectableChannel 中定义
(3)设置一个通道的阻塞模式,只要调用 configureBlocking 方法即可,传递参数值为 true,则设为阻塞模式,参数值为 false 值设为非阻塞模式
(4)isBlocking() 判断某个 Socket 通道当前处于哪种模式
3、阻塞模式下,相关方法都会导致线程暂停
(1)ServerSocketChannel.accept 会在没有连接建立时让线程暂停
(2)SocketChannel.read 会在通道中没有数据可读时让线程暂停
(3)阻塞是暂停线程,暂停期间不会占用 CPU
4、单线程下,阻塞方法之间相互影响,几乎不能正常工作,需要多线程支持
5、多线程下的问题
(1)32 位 JVM 一个线程 320k,64 位 JVM 一个线程 1024k,如果连接数过多,必然导致 OOM,并且线程太多,反而会因为频繁上下文切换导致性能降低
(2)线程池技术减少线程数、线程上下文切换,多连接长时间 inactive,会阻塞线程池中所有线程,因此不适合长连接,只适合短连接
6、非阻塞
(1)通过 ServerSocketChannel 的 configureBlocking(false),将获得连接设置为非阻塞,若此时若没有连接,accept 会返回 null
(2)通过 SocketChannel 的 configureBlocking(false),将从通道中读取数据设置为非阻塞,若此时通道中没有数据可读,read 会返回 -1
(3)在非阻塞情况下,不使用 while(true) 检查连接 / 可读数据,CPU 一直处于忙碌状态,会使得性能变低
SelectableChannel
public abstract class SelectableChannel
extends AbstractInterruptibleChannel
implements Channel
1、一个可以通过选择器进行复用的通道
2、为了与选择器一起使用,这个类的一个实例必须首先通过 register 方法注册,这个方法返回一个新的 SelectionKey 对象,代表该通道与选择器的注册
(1)一旦在一个选择器上注册,通道就会一直保持注册状态,直到它被注销,这包括注销选择器分配给该通道的任何资源
(2)一个通道不能被直接注销,相反,代表其注册的键必须被注销
(3)注销一个键,要求在选择器的下一次选择操作中注销通道
(4)一个键可以通过调用它的注销方法,以显示地被注销
(5)当通道被关闭时,所有通道的键都会被隐式地注销,不管是通过调用它的关闭方法,还是通过中断被阻塞在通道上的 I/O 操作的线程
(6)如果选择器本身被关闭,那么该通道将被注销,代表其注册的键也将失效,不会再有延迟
(7)一个通道最多可以在任何特定的选择器上注册一次
(8)一个通道是否被一个或多个选择器注册,可以通过调用 isRegistered 方法来确定
(9)SelectableChannel 对于多个并发的线程来说是安全的
3、阻塞模式
(1)一个 SelectableChannel 要么处于阻塞模式,要么处于非阻塞模式
(2)在阻塞模式下,每个在通道上调用的 I/O 操作将被阻塞,直到完成
(3)在非阻塞模式下,I/O 操作将永远不会阻塞,并且可能传输比要求的更少的字节,或者可能根本没有字节
(4)一个 SelectableChannel 的阻塞模式,可以通过调用它的 isBlocking 方法来确定
(5)新创建的 SelectableChannel 总是处于阻塞模式
(6)非阻塞模式在与基于选择器的多路复用一起使用时最有用
(7)一个通道在被注册到一个选择器之前必须被置于非阻塞模式,并且在它被注销之前不能被返回到阻塞模式
SocketOption
public interface SocketOption<T>
1、与 Socke 关联的 SocketOption
2、在 channels 程序包中,NetworkChannel 接口定义 setOption 和 getOption 方法,来设置和查询通道的 SocketOption
3、StandardSocketOptions
public final class StandardSocketOptions extends Object
(1)定义标准 SocketOption 实现
(2)这个类定义的每个 SocketOption 的 name 是它的字段名称
AbstractSelectableChannel
public abstract class AbstractSelectableChannel
extends SelectableChannel
1、SelectableChannel 的基本实现类
2、这个类定义了处理通道注册、注销、关闭的机制的方法
3、它保持该通道的当前阻塞模式以及其当前的选择键组
4、它执行实现 SelectableChannel 规范所需的所有同步,在此类中定义的抽象受保护方法的实现,不需要与可能从事相同操作的其他线程同步
5、调整此通道的阻塞模式
public final SelectableChannel configureBlocking(boolean block) throws IOException
(1)如果给定阻塞模式与当前阻塞模式不同,则该方法调用implConfigureBlocking方法,同时保持适当的锁,以便更改模式
(2)block:如果为 true,那么这个通道将被置于阻塞模式;如果为 false,那么它将被放置为非阻塞模式
(3)返回调用者
6、使用给定的选择器注册此通道,返回一个 SelectionKey
public final SelectionKey register(Selector sel,
int ops,
Object att)
throws ClosedChannelException
(1)该方法首先验证该通道是否打开,并且给定的初始兴趣集合是有效的
(2)如果该通道已经向给定的选择器注册,那么在将其兴趣设置为给定值之后,返回表示该注册的 SelectionKey
(3)否则,该通道尚未注册到给定的选择器,因此在保持适当的锁定的同时,调用选择器的 register 方法,生成的密钥将在返回之前,添加到此通道的密钥集中
(4)sel:要注册该通道的选择器
(5)ops:为所得密钥设置的兴趣
(6)att:所得密钥的附件,可能是 null
(7)返回表示该通道与给定选择器的注册的键
7、告知这个通道上的每个 I/O 操作是否会阻塞
public final boolean isBlocking()
(1)新创建的通道始终处于阻塞模式
(2)如果此通道关闭,则此方法返回的值未指定
(3)当此通道处于阻塞模式时,返回 true
8、告知这个通道当前是否在任何选择器上注册
public final boolean isRegistered()
(1)由于键取消和通道注销之间的固有延迟,在所有键被取消之后,通道可能会保留一段时间
(2)通道关闭后也可能会保留一段时间
(3)该通道被注册,返回 true
9、检索代表通道在给定选择器上的注册的键
public final SelectionKey keyFor(Selector sel)
(1)sel:选择器
(2)返回该通道最后一次注册到给定的选择器时返回的键
(3)如果此通道当前未注册到该选择器,返回 null
ServerSocketChannel
public abstract class ServerSocketChannel
extends AbstractSelectableChannel
implements NetworkChannel
1、用于面向流的监听 Socket 的 ServerSocketChannel
2、通过调用此类的 open 方法创建服务器套接字通
3、不可能为一个任意的、预先存在的 ServerSocket 创建一个通道
4、新创建的 ServerSocketChannel 已打开但尚未绑定,尝试调用未绑定 ServerSocketChannel 的 accept 方法,将导致抛出 NotYetBoundException
5、可以通过调用此类定义的 bind 方法之一来绑定 ServerSocketChannel
6、SocketOption 使用 setOption 方法进行配置,服务器端口通道支持以下选项
(1)SO_RCVBUF:Socket 接收缓冲区的大小
(2)SO_REUSEADDR:重用地址
(3)可以支持其他具体实现的选项
7、ServerSocketChannel 可以安全地被多个并发线程使用
8、实现类:ServerSocketChannelImpl
9、打开 ServerSocketChannel
public static ServerSocketChannel open() throws IOException
(1)通过调用系统范围默认的 SelectorProvider 对象的 openServerSocketChannel 方法创建新通道
(2)新通道的 ServerSocket 最初未绑定,必须通过其 ServerSocket 的 bind 方法将其绑定到特定的地址,才能接受连接
(3)返回一个新的 ServerSocketChannel
10、检索与此通道关联的 ServerSocket
public abstract ServerSocket socket()
(1)返回的对象不会声明任何未在 ServerSocket 类中声明的公共方法
11、设置 ServerSocket 选项的值
public abstract <T> ServerSocketChannel setOption(SocketOption<T> name, T value) throws IOException
(1)T:套接字选项值的类型
(2)name:Socket 选项
(3)value:Socket 选项的值,null 值可能是某些套接字选项的有效值
12、将通道的 ServerSocket 绑定到本地地址,并配置 ServerSocket 以监听连接
public final ServerSocketChannel bind(SocketAddress local) throws IOException
(1)此方法的调用等同于:bind(local, 0);
(2)local:绑定 ServerSocket 的本地地址;若为 null,绑定到自动分配的 SocketAddress
13、将通道的 SocketAddress 绑定到本地地址,并配置 SocketAddress 以监听连接
public abstract ServerSocketChannel bind(SocketAddress local,
int backlog)
throws IOException
(1)该方法用于在 SocketAddress 和本地地址之间建立关联,一旦建立关联,则套接字保持绑定,直到通道关闭
(2)backlog 参数是 ServerSocket 上待处理连接的最大数量,它的确切语义是由具体的实现决定的,特别是,一个实现可以强加一个最大长度,也可以选择忽略这个参数,如果参数值是 0,或为负值,那么使用一个特定的实现默认值
(3)local:绑定 SocketAddress,传入 null,则绑定到自动分配的 SocketAddress
(4)backlog:待处理连接的最大数量
14、接受与此 ServerSocketChannel 的连接
public abstract SocketChannel accept() throws IOException
(1)如果该信道是在非阻塞模式,如果没有待处理的连接,则此方法将立即返回 null,否则,它将无限期地阻塞,直到有新的连接或发生 I/O 错误
(2)无论此通道的阻塞模式如何,通过此方法返回的 SocketChannel(如果有)将处于阻塞模式
(3)该方法执行与 ServerSocket 类的 accept 方法完全相同的安全检查,即如果已经安装了一个安全管理器,那么对于每个新的连接,该方法将通过安全管理器的 checkAccept 方法,验证连接的远程端点的地址和端口号是否被允许
(4)返回用于新连接的 SocketChannel,或 null,如果此通道处于非阻塞模式,并且没有可接受的连接
(5)如果此通道处于非阻塞模式,并且没有可接受的连接,返回 null
15、返回此通道的 ServerSocket 所绑定的 SocketAddress
public abstract SocketAddress getLocalAddress() throws IOException
(1)当通道是 bind 到 IP Socket 地址,则此方法的返回值为 InetSocketAddress
(2)如果有一个安全管理器集,它的 checkConnect 方法被调用本地地址,并且 -1 作为参数来查看是否允许该操作,如果不允许的操作,SocketAddress 代表 loopback 地址和通道的套接字的本地端口返回
(3)如果有一个安全管理器被设置,它的 checkConnect 方法被调用,参数是本地地址和 -1,以查看操作是否被允许,如果操作不被允许,就会返回一个代表回环地址和 ServerSocket 的本地端口的 SocketAddress
(4)返回该 ServerSocket 被绑定的 SocketAddress,如果被安全管理器拒绝,则返回代表环回地址的SocketAddress,如果该通道的套接字没有被绑定,则返回null
DatagramChannel
public abstract class DatagramChannel
extends AbstractSelectableChannel
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, MulticastChannel
1、一个用于面向数据报的套接字的 SelectableChannel
2、通过调用此类的 open 方法创建 DatagramChannel,不可能为任意的、预先存在的 DatagramSocket 创建一个通道
3、新创建的 DatagramChannel 已打开但未连接,无需连接数据报通道,以便使用 send 和 receive 方法
4、可以通过调用其 connect 方法来连接 DatagramChannel,以避免安全检查的开销作为每个发送和接收操作的一部分
5、为了使用 read 和 write 方法,必须连接数据报通道,因为这些方法不接受或返回套接字地址
6、一旦连接,DatagramChannel 就会保持连接,直到它被断开或关闭,一个 DatagramChannel 是否被连接,可以通过调用其 isConnected 方法来确定
7、SocketOption 是通过 setOption 方法来配置的,一个到 IP Socket 的 DatagramChannel 支持以下选项
(1)SO_SNDBUF:套接字发送缓冲区的大小
(2)SO_RCVBUF:套接字接收缓冲区的大小
(3)SO_REUSEADDR:重复使用地址
(4)SO_BROADCAST:允许传输广播数据报
(5)IP_TOS:IP 报头中的服务类型(ToS)八位数
(6)IP_MULTICAST_IF:用于 IP 多播数据报的网络接口
(7)IP_MULTICAST_TTL:IP 多播数据包的生存时间
(8)IP_MULTICAST_LOOP:IP 多播数据包的回环
(9)可以支持其他(具体实现)的选项
8、DatagramChannel 对于多个并发线程的使用是安全的,它们支持并发的读和写,尽管在任何时候最多只有一个线程在读,最多只有一个线程在写
9、实现类:DatagramChannelImpl
10、打开 DatagramChannel
public static DatagramChannel open() throws IOException
(1)新通道是通过调用系统范围的默认 SelectorProvider 对象的 openDatagramChannel 方法创建的,通道不会连接
(2)DatagramSocket 的 ProtocolFamily 是平台(可能是配置),因此是未指定的
(3)open 允许在打开 DatagramChannel 时选择 ProtocolFamily,并且应该用于打开用于 IP 组播的 DatagramChannel
11、检索与此通道相关联的 DatagramSocket
public abstract DatagramSocket socket()
(1)返回的对象不会声明任何未在 DatagramSocket 类中声明的公共方法
12、将通道的 DatagramSocket 绑定到本地地址
public abstract DatagramChannel bind(SocketAddress local) throws IOException
(1)该方法用于在 DatagramSocket 和本地地址之间建立关联,一旦建立关联,则 DatagramSocket 保持绑定,直到通道关闭
(2)如果 local 参数的值为 null,则 DatagramSocket 将被绑定到自动分配的地址
(3)local:绑定 DatagramSocket 的地址,传入 null 将套接字绑定到自动分配的套接字地址
13、连接此通道的 DatagramSocket
public abstract DatagramChannel connect(SocketAddress remote) throws IOException
(1)通道的 DatagramSocket 被配置为仅从给定的远程对等地址接收数据报,并发送数据报
(2)一旦连接,数据报可能不会被接收或发送到任何其他地址
(3)DatagramSocket 保持连接,直到它被明确地断开或直到它被关闭
(4)该方法执行与 DatagramSocket 类的 connect 方法完全相同的安全检查,即如果已经安装了安全管理器,则该方法验证其 checkAccept 和 checkConnect 方法,是否允许分别从给定的远程地址接收数据报并发送给它们
(5)可以随时调用此方法,它在对被调用的时刻已经进行的读取或写入操作不会有任何影响
(6)如果此通道的 DatagramSocket 未绑定,则此方法将首先使 DatagramSocket 绑定到自动分配的地址,就像调用参数为 null 的 bind 方法
(7)remote:要连接此通道的远程地址
14、断开此通道的 DatagramSocket
public abstract DatagramChannel disconnect() throws IOException
(1)通道的 DatagramSocket 被配置为使得它可以从任何远程地址接收数据报,并发送数据报,只要安全管理器(如果已安装)就允许它
(2)可以随时调用此方法,它在对被调用的时刻已经进行的读取或写入操作不会有任何影响
(3)如果此通道的插座未连接,或者通道关闭,则调用此方法不起作用
15、返回此通道的 DatagramSocket 所绑定的 SocketAddress
public abstract SocketAddress getLocalAddress() throws IOException
(1)如果通道被绑定到一个 IP socket address,那么这个方法的返回值是 InetSocketAddress 类型
(2)如果有一个安全管理器被设置,它的 checkConnect 方法被调用,参数是本地地址和 -1,以查看操作是否被允许,如果操作不被允许,就会返回一个代表回环地址和通道套接字的本地端口的 SocketAddress
(3)返回 DatagramSocket 所绑定的 SocketAddress,如果被安全管理器拒绝,则代表回环地址的 SocketAddress,如果通道的套接字没有被绑定,则为 null
16、返回此通道的 DatagramSocket 所连接的远程地址
public abstract SocketAddress getRemoteAddress() throws IOException
(1)如果通道的 DatagramSocket 未连接,返回 null
17、告知这个通道的 DatagramSocket 是否连接
public abstract boolean isConnected()
(1)通道的 DatagramSocket 打开并连接,则返回 true
18、从此通道读取数据报
public abstract int read(ByteBuffer dst) throws IOException
(1)此方法只能在该通道的 DatagramSocket 连接时被调用,并且只接受 DatagramSocket 对等体的数据报
(2)如果数据报中存在比保留在给定缓冲区中更多的字节,则数据报的其余部分将被静默地丢弃,否则,此方法的行为与 ReadableByteChannel 接口中的规定完全相同
(3)dst:要传输字节的缓冲区
(4)返回读取的字节数,可能为 0,如果通道已达到流出端,则为 -1
19、通过该通道接收数据报
public abstract SocketAddress receive(ByteBuffer dst) throws IOException
(1)如果数据报可以立即可用,或者如果此通道处于阻塞模式,并且最终变为可用,则将数据报复制到给定的字节缓冲区中,并返回其源地址
(2)如果此通道处于非阻塞模式,并且数据报不能立即可用,则此方法立即返回 null
(3)数据报从其当前位置开始传输到给定的字节缓冲区,就像通常的 read 操作一样
(4)如果缓冲区中剩余的字节比保存数据报所需的字节少,则数据报的其余部分将被静默地丢弃
(5)该方法执行与 DatagramSocket 类的 receive 方法完全相同的安全检查,即如果 DatagramSocket 没有连接到特定的远程地址,并且已经安装了安全管理器,那么对于接收到的每个数据报,该方法都会验证源地址和端口号是否被安全管理器的 checkAccept 方法所允许,这个安全检查的开销可以通过首先通过 connect 方法连接 Socket 来避免
(6)可以随时调用此方法,但是,如果另一个线程已经在该通道上启动了读取操作,那么此方法的调用将阻塞,直到第一个操作完成
(7)如果此通道的套接字未绑定,则此方法将首先使 DatagramSocket 绑定到自动分配的地址,就像调用参数为 null 的 bind 方法
(8)dst:数据报传输到的缓冲区
(9)返回数据报的源地址,如果该通道处于非阻塞模式,没有数据报可以立即使用,则为 null
20、将数据报写入此通道
public abstract int write(ByteBuffer src) throws IOException
(1)此方法只能在该通道的 DatagramSocket 连接时被调用,在这种情况下,它将数据报直接发送到 DatagramSocket 的对等体,否则它的行为与 WritableByteChannel 中的规定完全相同
(2)src:要检索字节的缓冲区
(3)返回写入的字节数,可能为 0
21、通过此通道发送数据报
public abstract int send(ByteBuffer src,
SocketAddress target)
throws IOException
(1)如果该通道处于非阻塞模式,并且底层输出缓冲区中有足够的空间,或者如果该通道处于阻塞模式并且充足的空间变得可用,则给定缓冲区中的剩余字节作为单个数据报传输到给定目标地址
(2)数据报从字节缓冲区传送,就像通过常规的 write 操作一样
(3)该方法执行与 DatagramSocket 类的 send 方法完全相同的安全检查,即如果套接字未连接到特定的远程地址,并且安全管理器已经安装,则对于发送的每个数据报,该方法会验证目标地址和端口号是否被安全管理器的 checkConnect 方法所允许,这个安全检查的开销可以通过首先通过 connect 方法连接 Socket 来避免。
(4)可以随时调用此方法,但是,如果另一个线程已经在该通道上启动了写入操作,那么此方法的调用将阻塞,直到第一个操作完成
(5)如果此通道的 DatagramSocket 未绑定,则此方法将首先使 DatagramSocket 绑定到自动分配的地址,就像通过调用参数为 null 的 bind 方法
(6)src:包含要发送的数据报的缓冲区
(7)target:要发送数据报的地址
(8)返回发送的字节数,这是调用此方法时在源缓冲区中剩余的字节数,或者如果此通道不阻塞,如果底层输出缓冲区中没有足够的空间容纳数据报,则可能为 0
22、设置 DatagramSocket 选项的值
public abstract <T> DatagramChannel setOption(SocketOption<T> name, T value) throws IOException
(1)T:SocketOption 值的类型
(2)name:SocketOption 名称
(3)value:SocketOption 值,值为 null 可能是某些 SocketOption 的有效值
SocketChannel
public abstract class SocketChannel
extends AbstractSelectableChannel
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel
1、一个 SelectableChannel,用于面向流的连接 Socket
2、通过调用此类的 open 方法之一创建 SocketChannel,不可能为任意的、预先存在的 Socket 创建一个通道
3、新创建的 SocketChannel 已打开但尚未连接,尝试在未连接的通道上调用 I/O 操作,将导致抛出 NotYetConnectedException
4、可以通过调用其 connect 方法连接 SocketChannel;一旦连接,SocketChannel 保持连接,直到其被关闭,是否连接 SocketChannel 可以通过调用其 isConnected 方法来确定
5、SocketChannel 支持非阻塞连接
6、创建 SocketChannel,建立与远程 Socket 的链接的过程可以通过 connect 方法启动,随后由 finishConnect 方法完成,连接操作是否正在进行可以通过调用 isConnectionPending 方法来确定
7、SocketChannel 支持异步关闭,类似于 Channel 类中指定的异步关闭操作
(1)如果 Socket 的输入端由一个线程关闭,而另一个线程在 SocketChannel 的读操作中被阻塞,则阻塞线程中的读操作将完成,而不读任何字节,并将返回 -1
(2)如果 Socket 的输出端由一个线程关闭,而另一个线程在 SocketChannel 的写操作中被阻塞,则阻塞的线程将接收到一个 AsynchronousCloseException
8、SocketOption 是用 setOption 方法配置的,SocketChannel 支持以下选项
(1)SO_SNDBUF:套接字发送缓冲区的大小
(2)SO_RCVBUF:套接字接收缓冲区的大小
(3)SO_KEEPALIVE:保持连接状态
(4)SO_REUSEADDR:重复使用地址
(5)SO_LINGER:如果有数据存在,则在关闭时尝试发送数据(仅当配置为阻塞模式时)
(6)TCP_NODELAY:禁用 Nagle 算法
(7)支持其他(具体实现)的选项
9、SocketChannel 对于多个并发线程来说是安全的
(1)它们支持并发的读和写,尽管在任何时候最多只有一个线程在读,最多只有一个线程在写
(2)connect 和 finishConnect 方法是相互同步的,当这些方法之一的调用正在进行时,试图启动一个读或写的操作将被阻止,直到该调用完成
10、打开 SocketChannel
public static SocketChannel open() throws IOException
(1)通过调用系统范围的默认 SelectorProvider 对象的 openSocketChannel 方法创建新通道
(2)返回一个新的 SocketChannel
11、打开 SocketChannel,并将其连接到远程地址
public static SocketChannel open(SocketAddress remote) throws IOException
(1)这种方便的方法就像通过调用 open() 方法一样工作,调用 connect 方法在产生的套接字通道上传递 remote,然后返回该通道
(2)remote:要连接新通道的远程地址
(3)一个新的和连接的 SocketChannel
12、连接此通道的 Socket
public abstract boolean connect(SocketAddress remote) throws IOException
(1)如果此通道处于非阻塞模式,则此方法的调用将启动非阻塞连接操作,如果立即建立连接,就像本地连接一样,该方法返回 true, 否则,此方法返回 false,并且连接操作必须稍后通过调用 finishConnect 方法完成
(2)如果此通道处于阻塞模式,则该方法的调用将阻塞,直到建立连接或发生 I/O 错误
(3)此方法执行与 Socket 类完全相同的安全检查,即如果安装了一个安全管理器,则该方法验证其 checkConnect 方法是否允许连接到给定远程端点的地址和端口号
(4)可以随时调用此方法,如果在调用此方法时调用此通道的读取或写入操作,则该操作将首先阻止,直到此调用完成,如果连接尝试启动但失败,也就是说,如果此方法的调用抛出已检查的异常,则该通道将被关闭
(5)remote:要连接该通道的远程地址
(6)如果连接建立,返回 true;如果该通道处于非阻塞模式并且连接操作正在进行中,返回 false
13、完成连接 SocketChannel 的过程
public abstract boolean finishConnect() throws IOException
(1)通过将 SocketChannel 置于非阻塞模式,然后调用其 connect 方法来启动非阻塞连接操作,一旦建立了连接,或尝试失败,SocketChannel 将变得可连接,并且可以调用该方法来完成连接顺序,如果连接操作失败,则调用此方法将导致适当的 IOException 被抛出
(2)如果此通道已连接,则此方法将不会阻止并立即返回 true
(3)如果此通道处于非阻塞模式,且连接过程尚未完成,则此方法将返回 false
(4)如果此通道处于阻塞模式,则该方法将阻塞,直到连接完成或失败,并且将始终返回 true 或抛出描述失败的已检查异常
(5)可以随时调用此方法,如果在调用此方法时调用此通道的读取或写入操作,则该操作将首先阻塞,直到此调用完成,如果连接尝试失败,也就是说,如果此方法的调用引发已检查的异常,那么该通道将被关闭
(6)当此通道的 Socket 现在已连接,返回 true
14、将通道的 Socket 绑定到本地地址
public abstract SocketChannel bind(SocketAddress local) throws IOException
(1)该方法用于在 Socket 和本地地址之间建立关联
(2)一旦建立关联,则 Socket 保持绑定,直到通道关闭
(3)如果 local 参数的值为 null,则 Socket 将被绑定到自动分配的地址
(4)local:绑定 Socket 的地址,若传入 null,将 Socket 绑定到自动分配的套接字地址
15、返回此通道的 Socket 所绑定的 SocketAddress
public abstract SocketAddress getLocalAddress() throws IOException
(1)如果通道被绑定到一个 IP SocketAddress,那么这个方法的返回值是 InetSocketAddress 类型
(2)如果有一个安全管理器被设置,它的 checkConnect 方法会被调用,参数是本地地址和 -1,以查看操作是否被允许,如果操作不被允许,就会返回一个代表回环地址和通道的 Socket 的本地端口的 SocketAddress
(3)返回该 Socket 被绑定的 SocketAddress,如果被安全管理器拒绝,则返回代表环回地址的 SocketAddress,如果该通道的 Socket 没有被绑定,则返回 null
16、返回此通道的 Socket 所连接的远程地址
public abstract SocketAddress getRemoteAddress() throws IOException
(1)通道绑定并连接到 IP Socket 地址时,此方法的返回值为 InetSocketAddress
(2)返回远程地址;如果通道的插座未连接,返回 null
17、告知本通道的网络 Socket 是否连接
public abstract boolean isConnected()
(1)当且仅当这个通道的网络套接字是开放的,并且是连接的,返回 true
18、告知该通道上是否有连接操作正在进行中
public abstract boolean isConnectionPending()
(1)当且仅当这个通道上的连接操作已经开始,但尚未通过调用 finishConnect 方法完成,返回 true
19、从该通道读取到给定缓冲区的字节序列
public abstract int read(ByteBuffer dst) throws IOException
(1)尝试从通道读取 r 个字节,其中 r 是缓冲区中剩余的字节数,即 dst.remaining()
(2)假设读取长度为n的字节序列,其中 0 <= n <= r ,该字节序列将被转移到缓冲器,使得序列中的第一个字节是在索引 p 和最后一个字节是在索引 p + n - 1,其中 p 是该缓冲区的在调用此方法的瞬间位置
(3)缓冲区的返回位置将等于 p + n;其 limit 将不会改变
(4)读取操作可能不会填充缓冲区,实际上它可能不会读取任何字节。 是否这样做取决于渠道的性质和状态,例如,非阻塞模式的 SocketChannel 不能再读取比从 Socket 的输入缓冲区可以立即获得的任何字节数;但是,如果通道处于阻塞模式,并且缓冲区中至少剩余一个字节,则该方法将被阻塞,直到读取至少一个字节为止
(5)可以随时调用此方法,但是,如果另一个线程已经在该通道上启动了读取操作,那么此方法的调用将阻塞,直到第一个操作完成
(6)dst:要传输字节的缓冲区
(7)返回读取的字节数,可能为 0,如果通道已达到流出端, 则为 -1
20、从给定的缓冲区向该通道写入一个字节序列
public abstract int write(ByteBuffer src) throws IOException
(1)尝试写入 r 个字节到通道,其中 r 是缓冲区中剩余的字节数,即 src.remaining()
(2)假设写入长度为 n 的字节序列,其中 0 <= n <= r,该字节序列将从索引 p 开始从缓冲区传送,其中 p 是调用该方法时缓冲区的位置;写入的最后一个字节的索引将为 p + n - 1
(3)缓冲区的返回位置将等于 p + n;其 limit 将不会改变
(4)除非另有规定,写入操作将仅在写入所有 r 个请求的字节后才会返回,某些类型的通道取决于它们的状态,可能仅写入一些字节,或者可能只写入一些字节,例如,在非阻塞模式下的 SocketChannel 不能再写入比 Socket 输出缓冲区中的任何字节更多的字节
(5)可以随时调用此方法,但是,如果另一个线程已经在该通道上启动了写入操作,那么此方法的调用将阻塞,直到第一个操作完成
(6)src:要检索字节的缓冲区
(7)饭hi写入的字节数,可能为 0
21、关闭连接进行读取,不关闭通道
public abstract SocketChannel shutdownInput() throws IOException
(1)一旦关机进行读取,则通道上的进一步读取将返回 -1,表示到达流末端
(2)如果连接的输入端已经关闭,则调用此方法没有任何作用
(3)返回此通道
22、关闭连接以进行写入,而不关闭通道
public abstract SocketChannel shutdownOutput() throws IOException
(1)一旦关闭写入,则进一步尝试写入通道会抛出 ClosedChannelException
(2)如果连接的输出端已经关闭,则调用此方法不起作用
(3)返回此通道
23、检索与此通道相关联的 Socket
public abstract Socket socket()
(1)返回的对象不会声明任何没有在 Socket 类中声明的公共方法
(2)返回与此通道相关联的 Socket
24、设置 SocketOption 的值
public abstract <T> SocketChannel setOption(SocketOption<T> name, T value) throws IOException
(1)T:SocketOption 值的类型
(2)name:SocketOption 字段名
(3)value:SocketOption 的值,值为 null 可能是某些 SocketOption 的有效值
(4)返回此通道
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战