模块  java.base
软件包  java.nio.channels

Class AsynchronousSocketChannel

  • 实现的所有接口
    CloseableAutoCloseableAsynchronousByteChannelAsynchronousChannelChannelNetworkChannel

    public abstract class AsynchronousSocketChannelextends Objectimplements AsynchronousByteChannel, NetworkChannel
    面向流的连接套接字的异步通道。

    异步套接字通道以两种方式之一创建。 通过调用此类定义的open方法之一创建新创建的AsynchronousSocketChannel 新创建的频道已打开但尚未连接。 A相连接AsynchronousSocketChannel当连接到的插座制成创建AsynchronousServerSocketChannel 无法为任意预先存在的socket创建异步套接字通道。

    通过调用其connect方法连接新创建的通道; 一旦连接,通道保持连接直到它关闭。 是否连接套接字通道可以通过调用其getRemoteAddress方法来确定。 尝试在未连接的通道上调用I / O操作将导致抛出NotYetConnectedException

    这种类型的通道可以安全地供多个并发线程使用。 它们支持并发读写,但最多只有一个读操作和一个写操作可以在任何时候都很出色。 如果线程在先前的读操作完成之前启动读操作,则将抛出ReadPendingException 类似地,尝试在上一次写入完成之前启动写操作将抛出WritePendingException

    使用setOption方法配置套接字选项。 异步套接字通道支持以下选项:

    Socket options
    Option Name 描述
    SO_SNDBUF The size of the socket send buffer
    SO_RCVBUF The size of the socket receive buffer
    SO_KEEPALIVE Keep connection alive
    SO_REUSEADDR Re-use address
    TCP_NODELAY Disable the Nagle algorithm
    还可以支持其他(特定于实现的)选项。

    超时

    此类定义的readwrite方法允许在启动读取或写入操作时指定超时。 如果在操作完成之前超时,则操作完成,异常为InterruptedByTimeoutException 超时可能使通道或底层连接处于不一致状态。 在实现不能保证尚未从通道读取字节的情况下,它将通道置于特定于实现的错误状态 随后尝试启动read操作会导致引发未指定的运行时异常。 类似地,如果write操作超时且实现无法保证字节尚未写入通道,则进一步尝试通道write会导致引发未指定的运行时异常。 超时结束后, 未定义 I / O操作的ByteBuffer或缓冲区序列的状态。 应丢弃缓冲区或至少必须注意确保在通道保持打开时不访问缓冲区。 所有接受超时参数的方法都会将值小于或等于零,以表示I / O操作不会超时。

    从以下版本开始:
    1.7
    • 构造方法详细信息

      • AsynchronousSocketChannel

        protected AsynchronousSocketChannel​(AsynchronousChannelProvider provider)
        初始化此类的新实例。
        参数
        provider - 创建此渠道的提供商
    • 方法详细信息

      • provider

        public final AsynchronousChannelProvider provider()
        返回创建此通道的提供程序。
        结果
        创建此渠道的提供商
      • open

        public static AsynchronousSocketChannel open()                                      throws IOException
        打开异步套接字通道。

        此方法返回绑定到默认组的异步套接字通道。此方法等效于计算表达式:

         open((AsynchronousChannelGroup)null); 
        结果
        一个新的异步套接字通道
        异常
        IOException - 如果发生I / O错误
      • shutdownInput

        public abstract AsynchronousSocketChannel shutdownInput()                                                 throws IOException
        在不关闭通道的情况下关闭连接以进行读取。

        一旦关闭读取,则进一步读取通道将返回-1 ,即流结束指示。 如果连接的输入端已经关闭,则调用此方法无效。 对未完成的读操作的影响取决于系统,因此未指定。 当套接字接收缓冲区中的数据尚未被读取或数据随后到达时,效果(如果有的话)也取决于系统。

        结果
        这个频道
        异常
        NotYetConnectedException - 如果此通道尚未连接
        ClosedChannelException - 如果此频道已关闭
        IOException - 如果发生其他一些I / O错误
      • getRemoteAddress

        public abstract SocketAddress getRemoteAddress()                                        throws IOException
        返回此通道的套接字连接的远程地址。

        如果通道绑定并连接到Internet协议套接字地址,则此方法的返回值为InetSocketAddress类型。

        结果
        远程地址; null如果未连接通道的插座
        异常
        ClosedChannelException - 如果频道已关闭
        IOException - 如果发生I / O错误
      • connect

        public abstract <A> void connect​(SocketAddress remote,                                 A attachment,                                 CompletionHandler<Void,​? super A> handler)
        连接此频道。

        此方法启动连接此通道的操作。 handler参数是在成功建立连接或无法建立连接时调用的完成处理程序。 如果无法建立连接,则关闭通道。

        此方法执行与Socket类完全相同的安全检查。 也就是说,如果安装了安全管理器,则此方法将验证其checkConnect方法是否允许连接到给定远程端点的地址和端口号。

        参数类型
        A - 附件的类型
        参数
        remote - 此通道要连接的远程地址
        attachment - 要附加到I / O操作的对象; 可以是null
        handler - 使用结果的处理程序
        异常
        UnresolvedAddressException - 如果给定的远程地址未完全解析
        UnsupportedAddressTypeException - 如果不支持给定远程地址的类型
        AlreadyConnectedException - 如果此频道已连接
        ConnectionPendingException - 如果此通道上的连接操作已在进行中
        ShutdownChannelGroupException - 如果通道组已终止
        SecurityException - 如果已安装安全管理器且不允许访问给定的远程端点
        另请参见:
        getRemoteAddress()
      • read

        public abstract <A> void read​(ByteBuffer dst,                              long timeout,                              TimeUnit unit,                              A attachment,                              CompletionHandler<Integer,​? super A> handler)
        从该通道读取一个字节序列到给定的缓冲区。

        此方法启动异步读取操作,以将此通道中的字节序列读取到给定缓冲区中。 handler参数是一个完成处理程序,在读取操作完成(或失败)时调用。 传递给完成处理程序的结果是读取的字节数或-1如果由于通道已到达流末尾而无法读取字节。

        如果指定了超时并且在操作完成之前超时,则操作将以InterruptedByTimeoutException异常完成 如果发生超时,并且实现无法保证尚未读取字节,或者不会从通道读取到给定缓冲区,则进一步尝试从通道读取将导致抛出非特定的运行时异常。

        否则,此方法的工作方式与AsynchronousByteChannel.read(ByteBuffer,Object,CompletionHandler)方法相同。

        参数类型
        A - 附件的类型
        参数
        dst - 要传输字节的缓冲区
        timeout - I / O操作完成的最长时间
        unit - timeout参数的时间单位
        attachment - 要附加到I / O操作的对象; 可以是null
        handler - 使用结果的处理程序
        异常
        IllegalArgumentException - 如果缓冲区是只读的
        ReadPendingException - 如果此通道上的读操作正在进行中
        NotYetConnectedException - 如果此通道尚未连接
        ShutdownChannelGroupException - 如果通道组已终止
      • read

        public final <A> void read​(ByteBuffer dst,                           A attachment,                           CompletionHandler<Integer,​? super A> handler)
        从界面复制的说明: AsynchronousByteChannel
        从该通道读取一个字节序列到给定的缓冲区。

        此方法启动异步读取操作,以将此通道中的字节序列读取到给定缓冲区中。 handler参数是一个完成处理程序,在读取操作完成(或失败)时调用。 传递给完成处理程序的结果是读取的字节数或-1如果由于通道已到达流末尾而无法读取字节。

        读操作可以从通道读取最多r个字节,其中r是缓冲区中剩余的字节数,即尝试读取时的dst.remaining() 其中r为0,读取操作立即完成,结果为0而不启动I / O操作。

        假设读取长度为n的字节序列,其中0 < n <= r 该字节序列将被转移到缓冲器,使得序列中的第一个字节是在索引p和最后一个字节是在索引p + Ñ - 1 ,其中p是该缓冲区的在执行读取的时刻的位置。 完成后,缓冲区的位置将等于p + n ; 它的限制不会改变。

        多个并发线程使用缓冲区并不安全,因此在操作完成之前应注意不要访问缓冲区。

        可以随时调用此方法。 某些通道类型可能不允许在任何给定时间有多个读取未完成。 如果线程在先前的读操作完成之前启动读操作,则将抛出ReadPendingException

        Specified by:
        read ,接口 AsynchronousByteChannel
        参数类型
        A - 附件的类型
        参数
        dst - 要传输字节的缓冲区
        attachment - 要附加到I / O操作的对象; 可以是null
        handler - 完成处理程序
        异常
        IllegalArgumentException - 如果缓冲区是只读的
        ReadPendingException - 如果通道不允许多个读取未完成且先前的读取尚未完成
        NotYetConnectedException - 如果此频道尚未连接
        ShutdownChannelGroupException - 如果通道组已终止
      • read

        public abstract <A> void read​(ByteBuffer[] dsts,                              int offset,                              int length,                              long timeout,                              TimeUnit unit,                              A attachment,                              CompletionHandler<Long,​? super A> handler)
        从该通道读取一系列字节到给定缓冲区的子序列。 此操作(有时称为散射读取)在实现将数据分组为由一个或多个固定长度标头后跟可变长度主体组成的段的网络协议时通常很有用。 handler参数是一个完成处理程序,在读取操作完成(或失败)时调用。 传递给完成处理程序的结果是读取的字节数或-1如果由于通道已到达流末尾而无法读取字节。

        此方法启动从此通道读取最多r个字节,其中r是给定缓冲区数组的指定子序列中剩余的总字节数,即

         dsts[offset].remaining()     + dsts[offset+1].remaining()     + ... + dsts[offset+length-1].remaining()
        在尝试读取的那一刻。

        假设读取长度为n的字节序列,其中0 < n <= r 直到该序列的第一个dsts[offset].remaining()字节被传送到缓冲器dsts[offset] ,直到下一个dsts[offset+1].remaining()字节被传送到缓冲器dsts[offset+1] ,依此类推,直到整个字节序列被传送到给定的缓冲器中。 尽可能多的字节传输到每个缓冲区,因此每个更新缓冲区的最终位置(最后更新的缓冲区除外)保证等于该缓冲区的限制。 底层操作系统可以对可以在I / O操作中使用的缓冲区的数量施加限制。 如果缓冲区数(剩余字节数)超过此限制,则使用操作系统允许的最大缓冲区数执行I / O操作。

        如果指定了超时并且在操作完成之前超时,那么它将以InterruptedByTimeoutException异常完成 如果发生超时,并且实现不能保证没有读取字节,或者不会从通道读取到给定缓冲区,那么进一步尝试从通道读取将导致抛出非特定的运行时异常。

        参数类型
        A - 附件的类型
        参数
        dsts - 要传输字节的缓冲区
        offset - 要传输字节的第一个缓冲区的缓冲区数组内的偏移量; 必须是非负数且不大于dsts.length
        length - 要访问的最大缓冲区数; 必须是非负数且不大于dsts.length - offset
        timeout - I / O操作完成的最长时间
        unit - timeout参数的时间单位
        attachment - 要附加到I / O操作的对象; 可以是null
        handler - 使用结果的处理程序
        异常
        IndexOutOfBoundsException - 如果 offsetlength参数的前提条件
        IllegalArgumentException - 如果缓冲区是只读的
        ReadPendingException - 如果此通道上的读操作正在进行中
        NotYetConnectedException - 如果此频道尚未连接
        ShutdownChannelGroupException - 如果通道组已终止
      • write

        public abstract <A> void write​(ByteBuffer src,                               long timeout,                               TimeUnit unit,                               A attachment,                               CompletionHandler<Integer,​? super A> handler)
        从给定缓冲区向该通道写入一个字节序列。

        此方法启动异步写入操作,以从给定缓冲区向此通道写入字节序列。 handler参数是完成处理程序,在写入操作完成(或失败)时调用。 传递给完成处理程序的结果是写入的字节数。

        如果指定了超时并且在操作完成之前超时,那么它将以InterruptedByTimeoutException异常完成 如果发生超时,并且实现不能保证字节尚未写入,或者不会从给定缓冲区写入通道,则进一步尝试写入通道将导致抛出非特定的运行时异常。

        否则,此方法的工作方式与AsynchronousByteChannel.write(ByteBuffer,Object,CompletionHandler)方法相同。

        参数类型
        A - 附件的类型
        参数
        src - 要从中检索字节的缓冲区
        timeout - I / O操作完成的最长时间
        unit - timeout参数的时间单位
        attachment - 要附加到I / O操作的对象; 可以是null
        handler - 使用结果的处理程序
        异常
        WritePendingException - 如果此通道上的写操作正在进行中
        NotYetConnectedException - 如果此通道尚未连接
        ShutdownChannelGroupException - 如果通道组已终止
      • write

        public final <A> void write​(ByteBuffer src,                            A attachment,                            CompletionHandler<Integer,​? super A> handler)
        从界面复制的说明: AsynchronousByteChannel
        从给定缓冲区向该通道写入一个字节序列。

        此方法启动异步写入操作,以从给定缓冲区向此通道写入字节序列。 handler参数是在写入操作完成(或失败)时调用的完成处理程序。 传递给完成处理程序的结果是写入的字节数。

        写操作可以向通道写入最多r个字节,其中r是缓冲区中剩余的字节数,即在尝试写入时的src.remaining() 其中r为0,写操作立即完成,结果为0而不启动I / O操作。

        假设写入长度为n的字节序列,其中0 < n <= r 该字节序列将从索引p开始从缓冲区传输,其中p是执行写入时缓冲区的位置; 写入的最后一个字节的索引将是p + n - 1 完成后,缓冲区的位置将等于p + n ; 它的限制不会改变。

        多个并发线程使用缓冲区并不安全,因此在操作完成之前应注意不要访问缓冲区。

        可以随时调用此方法。 某些通道类型可能不允许在任何给定时间多于一个写入。 如果线程在先前的写操作完成之前启动写操作,则将抛出WritePendingException

        Specified by:
        write在接口 AsynchronousByteChannel
        参数类型
        A - 附件的类型
        参数
        src - 要从中检索字节的缓冲区
        attachment - 要附加到I / O操作的对象; 可以是null
        handler - 完成处理程序对象
        异常
        WritePendingException - 如果通道不允许多个写入未完成且前一次写入尚未完成
        NotYetConnectedException - 如果此频道尚未连接
        ShutdownChannelGroupException - 如果通道组已终止
      • write

        public abstract <A> void write​(ByteBuffer[] srcs,                               int offset,                               int length,                               long timeout,                               TimeUnit unit,                               A attachment,                               CompletionHandler<Long,​? super A> handler)
        从给定缓冲区的子序列向该通道写入一个字节序列。 此操作(有时称为收集写入)在实现将数据分组为由一个或多个固定长度标头后跟可变长度主体的段组成的网络协议时通常很有用。 handler参数是完成处理程序,在写入操作完成(或失败)时调用。 传递给完成处理程序的结果是写入的字节数。

        此方法启动向该通道写入最多r个字节,其中r是给定缓冲区数组的指定子序列中剩余的总字节数,即

         srcs[offset].remaining()     + srcs[offset+1].remaining()     + ... + srcs[offset+length-1].remaining()
        在尝试写入的那一刻。

        假设写入长度为n的字节序列,其中0 < n <= r 截至第一srcs[offset].remaining()字节这个序列是从缓存写入srcs[offset] ,直到下一个srcs[offset+1].remaining()字节从缓冲区写入srcs[offset+1] ,依此类推,直到将整个字节序列写入。 从每个缓冲区写入尽可能多的字节,因此每个更新缓冲区的最终位置(最后更新的缓冲区除外)保证等于该缓冲区的限制。 底层操作系统可以对可以在I / O操作中使用的缓冲区的数量施加限制。 如果缓冲区数(剩余字节数)超过此限制,则使用操作系统允许的最大缓冲区数执行I / O操作。

        如果指定了超时并且在操作完成之前超时,那么它将以InterruptedByTimeoutException异常完成 如果发生超时,并且实现无法保证尚未写入字节,或者不会从给定缓冲区写入通道,则进一步尝试写入通道将导致抛出非特定的运行时异常。

        参数类型
        A - 附件的类型
        参数
        srcs - 要从中检索字节的缓冲区
        offset - 要从中检索字节的第一个缓冲区的缓冲区数组中的偏移量; 必须是非负数且不大于srcs.length
        length - 要访问的最大缓冲区数; 必须是非负数且不大于srcs.length - offset
        timeout - I / O操作完成的最长时间
        unit - timeout参数的时间单位
        attachment - 要附加到I / O操作的对象; 可以是null
        handler - 使用结果的处理程序
        异常
        IndexOutOfBoundsException - 如果 offsetlength参数的前提条件
        WritePendingException - 如果此通道上的写操作已在进行中
        NotYetConnectedException - 如果此频道尚未连接
        ShutdownChannelGroupException - 如果通道组已终止
      • getLocalAddress

        public abstract SocketAddress getLocalAddress()                                       throws IOException
        返回此通道的套接字绑定的套接字地址。

        如果通道是bound到Internet协议套接字地址,则此方法的返回值是InetSocketAddress类型。

        如果存在安全管理器集,则使用本地地址和-1作为其参数调用其checkConnect方法,以查看是否允许该操作。 如果不允许该操作,则SocketAddress表示loopback地址的SocketAddress和通道套接字的本地端口。

        Specified by:
        getLocalAddress ,接口 NetworkChannel
        结果
        SocketAddress这套接字绑定到,或 SocketAddress代表的环回地址,如果安全管理器拒绝,或 null如果通道的套接字不绑定
        异常
        ClosedChannelException - 如果频道已关闭
        IOException - If an I/O error occurs