Module  java.base
软件包  java.nio.channels

Class SocketChannel

  • All Implemented Interfaces:
    CloseableAutoCloseableByteChannelChannelGatheringByteChannelInterruptibleChannelNetworkChannelReadableByteChannelScatteringByteChannelWritableByteChannel


    public abstract class SocketChannel
    extends AbstractSelectableChannel
    implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel
    用于面向流的连接插座的可选通道。

    通过调用此类的open方法之一创建套接字通道。 不可能为任意的预先存在的套接字创建一个通道。 新创建的套接字通道已打开但尚未连接。 尝试在未连接的通道上调用I / O操作将导致抛出NotYetConnectedException 可以通过调用其connect方法连接套接字通道; 一旦连接,插座通道保持连接,直到其闭合。 可以通过调用其isConnected方法来确定套接字信道是否连接。

    套接字通道支持非阻塞连接:可以创建套接字通道,并且可以通过connect方法启动建立到远程套接字的链接的过程,以便稍后通过finishConnect方法完成。 连接操作是否正在进行可以通过调用isConnectionPending方法来确定。

    Socket通道支持异步关闭,类似于Channel类中指定的异步关闭操作。 如果套接字的输入端被一个线程关闭,而另一个线程在套接字通道的读操作中被阻塞,则阻塞线程中的读操作将完成,而不读取任何字节,并将返回-1 如果套接字的输出端由一个线程关闭,而另一个线程在套接字通道的写操作中被阻塞,则阻塞的线程将接收到一个AsynchronousCloseException

    套接字选项使用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
    SO_LINGER Linger on close if data is present (when configured in blocking mode only)
    TCP_NODELAY Disable the Nagle algorithm
    还可以支持附加(实现特定)选项。

    套接字通道可以安全地被多个并发线程使用。 他们支持并发阅读和写作,尽管最多只有一个线程可能正在读取,并且最多一个线程可能在任何给定的时间写入。 connectfinishConnect方法彼此相互同步,并且在调用这些方法之一时正在进行的启动读取或写入操作的尝试将被阻塞,直到该调用完成。

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

      • SocketChannel

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

      • open

        public static SocketChannel open​(SocketAddress remote)
                                  throws IOException
        打开套接字通道并将其连接到远程地址。

        这种方便的方法就像调用open()方法一样,在最终的套接字通道上调用connect方法,传递给它remote ,然后返回该通道。

        参数
        remote - 要连接新通道的远程地址
        结果
        一个新的和连接的插座通道
        异常
        AsynchronousCloseException - 如果另一个线程在连接操作进行过程中关闭此通道
        ClosedByInterruptException - 如果另一个线程在连接操作进行过程中中断当前线程,则关闭通道并设置当前线程的中断状态
        UnresolvedAddressException - 如果给定的远程地址未完全解析
        UnsupportedAddressTypeException - 如果不支持给定的远程地址的类型
        SecurityException - 如果已安装安全管理器,并且不允许访问给定的远程端点
        IOException - 如果发生其他I / O错误
      • shutdownInput

        public abstract SocketChannel shutdownInput​()
                                             throws IOException
        关闭连接进行阅读,不关闭频道。

        一旦关机进行读取,则通道上的进一步读取将返回-1流末端指示。 如果连接的输入端已经关闭,则调用此方法没有任何作用。

        结果
        这个频道
        异常
        NotYetConnectedException - 如果此频道尚未连接
        ClosedChannelException - 如果此通道关闭
        IOException - 如果发生其他I / O错误
        从以下版本开始:
        1.7
      • socket

        public abstract Socket socket​()
        检索与此通道相关联的套接字。

        返回的对象不会声明任何未在Socket类中声明的公共方法。

        结果
        与此通道相关联的插座
      • isConnected

        public abstract boolean isConnected​()
        告知本频道的网络插座是否连接。
        结果
        true如果,并且只有这个通道的网络套接字是 open并连接
      • isConnectionPending

        public abstract boolean isConnectionPending​()
        告知此频道是否正在进行连接操作。
        结果
        true如果并且只有在此通道上启动了连接操作但尚未通过调用 finishConnect方法完成
      • connect

        public abstract boolean connect​(SocketAddress remote)
                                 throws IOException
        连接此通道的插座。

        如果此通道处于非阻塞模式,则此方法的调用将启动非阻塞连接操作。 如果立即建立连接,就像本地连接一样,该方法返回true 否则,此方法返回false ,并且连接操作必须稍后通过调用finishConnect方法完成。

        如果此通道处于阻塞模式,则该方法的调用将阻塞,直到建立连接或发生I / O错误。

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

        可以随时调用此方法。 如果在调用此方法时调用此通道的读取或写入操作,则该操作将首先阻止,直到此调用完成。 如果连接尝试启动但失败,也就是说,如果此方法的调用抛出已检查的异常,则该通道将被关闭。

        参数
        remote - 要连接该通道的远程地址
        结果
        true如果连接建立, false如果此通道处于非阻塞模式并且连接操作正在进行中
        异常
        AlreadyConnectedException - 如果此频道已连接
        ConnectionPendingException - 如果此通道上已经进行了非阻塞连接操作
        ClosedChannelException - 如果此通道关闭
        AsynchronousCloseException - 如果另一个线程在连接操作进行过程中关闭此通道
        ClosedByInterruptException - 如果另一个线程在连接操作进行过程中中断当前线程,从而关闭通道并设置当前线程的中断状态
        UnresolvedAddressException - 如果给定的远程地址未完全解析
        UnsupportedAddressTypeException - 如果不支持给定的远程地址的类型
        SecurityException - 如果已安装安全管理器,并且不允许访问给定的远程端点
        IOException - 如果发生其他I / O错误
      • finishConnect

        public abstract boolean finishConnect​()
                                       throws IOException
        完成连接插座通道的过程。

        通过将套接字通道置于非阻塞模式,然后调用其connect方法来启动非阻塞连接操作。 一旦建立了连接,或尝试失败,套接字通道将变得可连接,并且可以调用该方法来完成连接顺序。 如果连接操作失败,则调用此方法将导致适当的IOException抛出。

        如果此通道已连接,则此方法将不会阻止,并将立即返回true 如果此通道处于非阻塞模式,则如果连接过程尚未完成,则此方法将返回false 如果此通道处于阻塞模式,则该方法将阻塞,直到连接完成或失败,并且将始终返回true或抛出描述故障的检查异常。

        可以随时调用此方法。 如果在调用此方法时调用此通道的读取或写入操作,则该操作将首先阻止,直到此调用完成。 如果连接尝试失败,也就是说,如果此方法的调用引发已检查的异常,那么该通道将被关闭。

        结果
        true如果,且仅当此通道的插座现在已连接
        异常
        NoConnectionPendingException - 如果该通道未连接,并且没有启动连接操作
        ClosedChannelException - 如果此通道关闭
        AsynchronousCloseException - 如果另一个线程在连接操作进行过程中关闭此通道
        ClosedByInterruptException - 如果另一个线程在连接操作进行过程中中断当前线程,从而关闭通道并设置当前线程的中断状态
        IOException - 如果发生其他I / O错误
      • getRemoteAddress

        public abstract SocketAddress getRemoteAddress​()
                                                throws IOException
        返回此通道的插座所连接的远程地址。

        通道绑定并连接到Internet协议套接字地址时,此方法的返回值为InetSocketAddress

        结果
        远程地址; null如果通道的插座未连接
        异常
        ClosedChannelException - 如果通道关闭
        IOException - 如果发生I / O错误
        从以下版本开始:
        1.7
      • read

        public abstract int read​(ByteBuffer dst)
                          throws IOException
        描述从接口ReadableByteChannel复制
        从该通道读取到给定缓冲区的字节序列。

        尝试从通道读取r个字节,其中r是缓冲区中剩余的字节数,即dst.remaining() ,在此方法被调用的时刻。

        假设读取长度为n的字节序列,其中0 <= n <= r 该字节序列将被转移到缓冲器,使得序列中的第一个字节是在索引p和最后一个字节是在索引p + Ñ - 1 ,其中p是该缓冲区的在调用此方法的瞬间位置。 一旦返回缓冲区的位置将等于p + n ; 其限制将不会改变。

        读取操作可能不会填充缓冲区,实际上它可能不会读取任何字节。 是否这样做取决于渠道的性质和状态。 例如,非阻塞模式的套接字通道不能再读取比从套接字的输入缓冲区立即可用的任何字节数; 类似地,文件通道不能读取比保留在文件中的任何更多的字节。 但是,如果通道处于阻塞模式,并且缓冲区中至少剩余一个字节,则该方法将被阻塞,直到读取至少一个字节为止。

        可以随时调用此方法。 但是,如果另一个线程已经在该通道上启动了读取操作,那么此方法的调用将阻塞,直到第一个操作完成。

        Specified by:
        read在接口 ReadableByteChannel
        参数
        dst - 要传输字节的缓冲区
        结果
        读取的字节数,可能为零,如果通道已达到流出端, -1
        异常
        NotYetConnectedException - 如果此频道尚未连接
        ClosedChannelException - 如果此通道关闭
        AsynchronousCloseException - 如果另一个线程在读取操作正在进行时关闭此通道
        ClosedByInterruptException - 如果另一个线程在读取操作正在进行时中断当前线程,从而关闭通道并设置当前线程的中断状态
        IOException - 如果发生其他I / O错误
      • read

        public abstract long read​(ByteBuffer[] dsts,
                                  int offset,
                                  int length)
                           throws IOException
        说明从界面ScatteringByteChannel复制
        从该通道读取字节序列到给定缓冲区的子序列中。

        该方法的调用尝试从该通道读取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]等等,直到整个字节序列被传送到给定的缓冲器。 尽可能多的字节被传送到每个缓冲器中,因此除了最后更新的缓冲器之外,每个更新的缓冲器的最终位置被保证等于该缓冲器的限制。

        可以随时调用此方法。 但是,如果另一个线程已经在该通道上启动了读取操作,那么此方法的调用将阻塞,直到第一个操作完成。

        Specified by:
        read接口 ScatteringByteChannel
        参数
        dsts - 要传输字节的缓冲区
        offset - 要传输字节的第一个缓冲区的缓冲区数组中的偏移量; 必须是非负数,不得大于dsts.length
        length - 要访问的最大缓冲区数; 必须是非负数,不得大于dsts.length - offset
        结果
        读取的字节数,可能为零,如果通道已达到流出端, -1
        异常
        NotYetConnectedException - 如果此频道尚未连接
        ClosedChannelException - 如果此通道关闭
        AsynchronousCloseException - 如果另一个线程在读取操作正在进行时关闭此通道
        ClosedByInterruptException - 如果另一个线程在读取操作正在进行中断当前线程,从而关闭通道并设置当前线程的中断状态
        IOException - 如果发生其他I / O错误
      • write

        public abstract int write​(ByteBuffer src)
                           throws IOException
        描述从接口WritableByteChannel复制
        从给定的缓冲区向该通道写入一个字节序列。

        尝试写入r个字节到通道,其中r是缓冲区中剩余的字节数,即src.remaining() ,在此方法被调用的时刻。

        假设长度为n的字节序列被写入,其中0 <= n <= r 该字节序列将从索引p开始从缓冲区传送,其中p是调用该方法时缓冲区的位置; 写入的最后一个字节的索引将为p + n - 1 一旦返回缓冲区的位置将等于p + n ; 其限制将不会改变。

        除非另有规定,写入操作将仅在写入所有r个请求的字节后才会返回。 某些类型的通道取决于它们的状态,可能仅写入一些字节,或者可能只写入一些字节。 例如,在非阻塞模式下的套接字通道不能写入任何比套接字输出缓冲区中的任何字节更多的字节。

        可以随时调用此方法。 但是,如果另一个线程已经在该通道上启动了写入操作,那么此方法的调用将阻塞,直到第一个操作完成。

        Specified by:
        write在接口 WritableByteChannel
        参数
        src - 要检索字节的缓冲区
        结果
        写入的字节数,可能为零
        异常
        NotYetConnectedException - 如果此频道尚未连接
        ClosedChannelException - 如果此通道关闭
        AsynchronousCloseException - 如果另一个线程在写操作正在进行时关闭此通道
        ClosedByInterruptException - 如果另一个线程在写操作正在进行时中断当前线程,从而关闭通道并设置当前线程的中断状态
        IOException - 如果发生其他I / O错误
      • write

        public abstract long write​(ByteBuffer[] srcs,
                                   int offset,
                                   int length)
                            throws IOException
        描述从接口GatheringByteChannel复制
        从给定缓冲区的子序列将一个字节序列写入该通道。

        尝试写入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]写入,等等,直到写入整个字节序列。 尽可能多的字节从每个缓冲区写入,因此除了最后更新的缓冲区之外,每个更新的缓冲区的最终位置被保证等于该缓冲区的限制。

        除非另有规定,写入操作将仅在写入所有r个请求的字节后才会返回。 某些类型的通道取决于它们的状态,可能仅写入一些字节,或者可能只写入一些字节。 例如,在非阻塞模式下的套接字通道不能写入任何比套接字输出缓冲区中的任何字节更多的字节。

        可以随时调用此方法。 但是,如果另一个线程已经在该通道上启动了写入操作,那么此方法的调用将阻塞,直到第一个操作完成。

        Specified by:
        write在接口 GatheringByteChannel
        参数
        srcs - 要检索字节的缓冲区
        offset - 要检索字节的第一个缓冲区的缓冲区数组中的偏移量; 必须是非负数,不得大于srcs.length
        length - 要访问的缓冲区的最大数量; 必须是非负数,不得大于srcs.length - offset
        结果
        写入的字节数,可能为零
        异常
        NotYetConnectedException - 如果此频道尚未连接
        ClosedChannelException - 如果此通道关闭
        AsynchronousCloseException - 如果另一个线程在写操作正在进行时关闭此通道
        ClosedByInterruptException - 如果另一个线程在写操作正在进行时中断当前线程,从而关闭通道并设置当前线程的中断状态
        IOException - 如果发生其他I / O错误
      • getLocalAddress

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

        通道为Internet协议套接字地址的bound ,则此方法的返回值为InetSocketAddress

        如果有一个安全管理器集,其checkConnect方法将以本地地址和-1作为参数来调用,以查看是否允许该操作。 如果不允许操作,则SocketAddress表示loopback地址的SocketAddress和通道插座的本地端口。

        Specified by:
        getLocalAddress接口 NetworkChannel
        结果
        SocketAddress的套接字绑定到,或 SocketAddress代表的环回地址,如果安全管理器拒绝,或者 null如果通道的套接字不绑定
        异常
        ClosedChannelException - 如果通道关闭
        IOException - 如果发生I / O错误