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
方法进行配置。 套接字通道支持以下选项:
还可以支持附加(实现特定)选项。
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
套接字通道可以安全地被多个并发线程使用。 他们支持并发阅读和写作,但最多只有一个线程可能正在读取,并且最多一个线程可能在任何给定的时间写入。 connect
和finishConnect
方法彼此相互同步,并且在调用这些方法之一的过程中尝试发起读取或写入操作将阻塞直到该调用完成。
Modifier | Constructor and Description |
---|---|
protected |
SocketChannel(SelectorProvider provider)
初始化此类的新实例。
|
Modifier and Type | Method and Description |
---|---|
abstract SocketChannel |
bind(SocketAddress local)
将通道的套接字绑定到本地地址。
|
abstract boolean |
connect(SocketAddress remote)
连接此通道的插座。
|
abstract boolean |
finishConnect()
完成连接插座通道的过程。
|
abstract SocketAddress |
getLocalAddress()
返回此通道的套接字所绑定的套接字地址。
|
abstract SocketAddress |
getRemoteAddress()
返回此通道的插座所连接的远程地址。
|
abstract boolean |
isConnected()
告知本频道的网络插座是否连接。
|
abstract boolean |
isConnectionPending()
告知此频道是否正在进行连接操作。
|
static SocketChannel |
open()
打开套接字通道。
|
static SocketChannel |
open(SocketAddress remote)
打开套接字通道并将其连接到远程地址。
|
abstract int |
read(ByteBuffer dst)
从该通道读取到给定缓冲区的字节序列。
|
long |
read(ByteBuffer[] dsts)
从该通道读取到给定缓冲区的字节序列。
|
abstract long |
read(ByteBuffer[] dsts, int offset, int length)
从该通道读取字节序列到给定缓冲区的子序列中。
|
abstract <T> SocketChannel |
setOption(SocketOption<T> name, T value)
设置套接字选项的值。
|
abstract SocketChannel |
shutdownInput()
关闭连接进行阅读,不关闭频道。
|
abstract SocketChannel |
shutdownOutput()
关闭连接以进行写入,而不关闭通道。
|
abstract Socket |
socket()
检索与此通道相关联的套接字。
|
int |
validOps()
返回确定此频道支持的操作的操作集。
|
abstract int |
write(ByteBuffer src)
从给定的缓冲区向该通道写入一个字节序列。
|
long |
write(ByteBuffer[] srcs)
从给定的缓冲区向该通道写入一系列字节。
|
abstract long |
write(ByteBuffer[] srcs, int offset, int length)
从给定缓冲区的子序列将一个字节序列写入该通道。
|
blockingLock, configureBlocking, implCloseChannel, implCloseSelectableChannel, implConfigureBlocking, isBlocking, isRegistered, keyFor, provider, register
register
begin, close, end, isOpen
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
getOption, supportedOptions
protected SocketChannel(SelectorProvider provider)
provider
- 创建此频道的提供商
public static SocketChannel open() throws IOException
通过调用系统范围的默认SelectorProvider
对象的openSocketChannel
方法创建新通道。
IOException
- 如果发生I / O错误
public static SocketChannel open(SocketAddress remote) throws IOException
这种方便的方法就像通过调用open()
方法一样工作,调用89419042942426方法在产生的套接字通道上传递remote ,然后返回该通道。
remote
- 要连接新通道的远程地址
AsynchronousCloseException
- 如果另一个线程在连接操作进行过程中关闭此通道
ClosedByInterruptException
- 如果另一个线程在连接操作进行过程中中断当前线程,则关闭通道并设置当前线程的中断状态
UnresolvedAddressException
- 如果给定的远程地址没有完全解决
UnsupportedAddressTypeException
- 如果不支持给定的远程地址的类型
SecurityException
- 如果已安装安全管理器,并且不允许访问给定的远程端点
IOException
- 如果发生其他I / O错误
public final int validOps()
套接字通道支持连接,读取和写入,因此该方法返回( SelectionKey.OP_CONNECT
| SelectionKey.OP_READ
| SelectionKey.OP_WRITE
) 。
validOps
在
SelectableChannel
public abstract SocketChannel bind(SocketAddress local) throws IOException
NetworkChannel
复制
该方法用于在套接字和本地地址之间建立关联。 一旦建立关联,则套接字保持绑定,直到通道关闭。 如果local
参数的值为null
则套接字将被绑定到自动分配的地址。
bind
在接口
NetworkChannel
local
- 绑定套接字的地址,或
null
将套接字绑定到自动分配的套接字地址
ConnectionPendingException
- 如果该通道上已经在进行非阻塞连接操作
AlreadyBoundException
- 如果套接字已经绑定
UnsupportedAddressTypeException
- 如果不支持给定地址的类型
ClosedChannelException
- 如果通道关闭
IOException
- 如果发生其他I / O错误
SecurityException
- 如果已安装安全管理员,并且其
checkListen
方法拒绝操作
NetworkChannel.getLocalAddress()
public abstract <T> SocketChannel setOption(SocketOption<T> name, T value) throws IOException
NetworkChannel
setOption
在接口
NetworkChannel
T
- 套接字选项值的类型
name
- 套接字选项
value
- 套接字选项的值。
值为null
可能是某些套接字选项的有效值。
UnsupportedOperationException
- 如果此通道不支持套接字选项
IllegalArgumentException
- 如果该值不是此套接字选项的有效值
ClosedChannelException
- 如果此通道关闭
IOException
- 如果发生I / O错误
StandardSocketOptions
public abstract SocketChannel shutdownInput() throws IOException
一旦关机进行读取,则通道上的进一步读取将返回-1
流末端指示。 如果连接的输入端已经关闭,则调用此方法没有任何作用。
NotYetConnectedException
- 如果此频道尚未连接
ClosedChannelException
- 如果此通道关闭
IOException
- 如果发生其他I / O错误
public abstract SocketChannel shutdownOutput() throws IOException
一旦关闭写入,则进一步尝试写入通道会抛出ClosedChannelException
。 如果连接的输出端已经关闭,则调用此方法不起作用。
NotYetConnectedException
- 如果此频道尚未连接
ClosedChannelException
- 如果此通道关闭
IOException
- 如果发生其他I / O错误
public abstract boolean isConnected()
open
并连接
public abstract boolean isConnectionPending()
finishConnect
方法完成
public abstract boolean connect(SocketAddress remote) throws IOException
如果此通道处于非阻塞模式,则此方法的调用将启动非阻塞连接操作。 如果立即建立连接,就像本地连接一样,该方法返回true 。 否则,此方法返回false ,并且连接操作必须稍后通过调用finishConnect
方法完成。
如果此通道处于阻塞模式,则该方法的调用将阻塞,直到建立连接或发生I / O错误。
此方法执行与Socket
类完全相同的安全检查。 也就是说,如果安装了一个安全管理器,则该方法验证其checkConnect
方法是否允许连接到给定远程端点的地址和端口号。
可以随时调用此方法。 如果在调用此方法时调用此通道的读取或写入操作,则该操作将首先阻止,直到此调用完成。 如果连接尝试启动但失败,也就是说,如果此方法的调用抛出已检查的异常,则该通道将被关闭。
remote
- 要连接该通道的远程地址
AlreadyConnectedException
- 如果此频道已连接
ConnectionPendingException
- 如果该通道上已经进行了非阻塞连接操作
ClosedChannelException
- 如果此通道关闭
AsynchronousCloseException
- 如果另一个线程在连接操作进行过程中关闭此通道
ClosedByInterruptException
- 如果另一个线程在连接操作正在进行时中断当前线程,从而关闭通道并设置当前线程的中断状态
UnresolvedAddressException
- 如果给定的远程地址未完全解析
UnsupportedAddressTypeException
- 如果不支持给定的远程地址的类型
SecurityException
- 如果已安装安全管理器,并且不允许访问给定的远程端点
IOException
- 如果发生其他I / O错误
public abstract boolean finishConnect() throws IOException
通过将套接字通道置于非阻塞模式,然后调用其connect
方法来启动非阻塞连接操作。 一旦建立了连接,或尝试失败,套接字通道将变得可连接,并且可以调用该方法来完成连接顺序。 如果连接操作失败,则调用此方法将导致适当的IOException
被抛出。
如果此通道已连接,则此方法将不会阻止并立即返回true 。 如果此通道处于非阻塞模式,则如果连接过程尚未完成,则此方法将返回false 。 如果此通道处于阻塞模式,则该方法将阻塞,直到连接完成或失败,并且将始终返回true或抛出描述失败的已检查异常。
可以随时调用此方法。 如果在调用此方法时调用此通道的读取或写入操作,则该操作将首先阻止,直到此调用完成。 如果连接尝试失败,也就是说,如果此方法的调用引发已检查的异常,那么该通道将被关闭。
NoConnectionPendingException
- 如果此通道未连接,并且未启动连接操作
ClosedChannelException
- 如果此通道关闭
AsynchronousCloseException
- 如果另一个线程在连接操作进行中时关闭此通道
ClosedByInterruptException
- 如果另一个线程在连接操作进行过程中中断当前线程,从而关闭通道并设置当前线程的中断状态
IOException
- 如果发生其他I / O错误
public abstract SocketAddress getRemoteAddress() throws IOException
通道绑定并连接到Internet协议套接字地址时,此方法的返回值为InetSocketAddress
。
null
如果通道的插座未连接
ClosedChannelException
- 如果通道关闭
IOException
- 如果发生I / O错误
public abstract int read(ByteBuffer dst) throws IOException
ReadableByteChannel
复制
尝试从通道读取r个字节,其中r是缓冲区中剩余的字节数,即dst.remaining() ,在该方法被调用的时刻。
假设读取长度为n的字节序列,其中88419044412022 <= n <= r 。 该字节序列将被转移到缓冲器,使得序列中的第一个字节是在索引p和最后一个字节是在索引p + -Ñ1,其中p是该缓冲区的在调用此方法的瞬间位置。 缓冲区的返回位置将等于p + n ; 其限制将不会改变。
读取操作可能不会填充缓冲区,实际上它可能不会读取任何字节。 是否这样做取决于渠道的性质和状态。 例如,非阻塞模式的套接字通道不能再读取比从套接字的输入缓冲区可以立即获得的任何字节数; 类似地,文件通道不能读取比保留在文件中的任何更多的字节。 但是,如果通道处于阻塞模式,并且缓冲区中至少剩余一个字节,则该方法将被阻塞,直到读取至少一个字节为止。
可以随时调用此方法。 但是,如果另一个线程已经在该通道上启动了读取操作,那么此方法的调用将阻塞,直到第一个操作完成。
read
在接口
ReadableByteChannel
dst
- 要传输字节的缓冲区
NotYetConnectedException
- 如果此频道尚未连接
ClosedChannelException
- 如果此通道关闭
AsynchronousCloseException
- 如果另一个线程在读取操作正在进行时关闭此通道
ClosedByInterruptException
- 如果另一个线程在读取操作正在进行中断当前线程,从而关闭通道并设置当前线程的中断状态
IOException
- 如果发生其他I / O错误
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]等等,直到整个字节序列被传送到给定的缓冲器。 尽可能多的字节被传送到每个缓冲器中,因此除了最后更新的缓冲器之外,每个更新的缓冲器的最终位置被保证等于该缓冲器的限制。
可以随时调用此方法。 但是,如果另一个线程已经在该通道上启动了读取操作,那么此方法的调用将阻塞,直到第一个操作完成。
read
在接口
ScatteringByteChannel
dsts
- 要传输字节的缓冲区
offset
- 要传输字节的第一个缓冲区的缓冲区中的偏移量;
必须是非负数,不得大于dsts.length
length
- 要访问的缓冲区的最大数量;
必须是非负数,不得大于dsts.length - offset
NotYetConnectedException
- 如果此频道尚未连接
ClosedChannelException
- 如果此通道关闭
AsynchronousCloseException
- 如果另一个线程在读取操作正在进行时关闭此通道
ClosedByInterruptException
- 如果另一个线程在读取操作正在进行时中断当前线程,从而关闭通道并设置当前线程的中断状态
IOException
- 如果发生其他I / O错误
public final long read(ByteBuffer[] dsts) throws IOException
ScatteringByteChannel
调用此方法的形式为c.read(dsts)的行为方式与调用完全相同
c.read(dsts, 0, dsts.length);
read
在界面
ScatteringByteChannel
dsts
- 要传输字节的缓冲区
NotYetConnectedException
- 如果此频道尚未连接
ClosedChannelException
- 如果此通道关闭
AsynchronousCloseException
- 如果另一个线程在读操作正在进行时关闭此通道
ClosedByInterruptException
- 如果另一个线程在读取操作正在进行中断当前线程,从而关闭通道并设置当前线程的中断状态
IOException
- 如果发生其他I / O错误
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个请求的字节后才会返回。 某些类型的通道取决于它们的状态,可能仅写入一些字节,或者可能只写入一些字节。 例如,在非阻塞模式下的套接字通道不能再写入比套接字输出缓冲区中的任何字节更多的字节。
可以随时调用此方法。 但是,如果另一个线程已经在该通道上启动了写入操作,那么此方法的调用将阻塞,直到第一个操作完成。
write
在接口
WritableByteChannel
src
- 要检索字节的缓冲区
NotYetConnectedException
- 如果此频道尚未连接
ClosedChannelException
- 如果此通道关闭
AsynchronousCloseException
- 如果另一个线程在写操作正在进行时关闭此通道
ClosedByInterruptException
- 如果另一个线程在写入操作进行过程中中断当前线程,从而关闭通道并设置当前线程的中断状态
IOException
- 如果发生其他I / O错误
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个请求的字节后才会返回。 某些类型的通道取决于它们的状态,可能仅写入一些字节,或者可能只写入一些字节。 例如,在非阻塞模式下的套接字通道不能再写入比套接字输出缓冲区中的任何字节更多的字节。
可以随时调用此方法。 但是,如果另一个线程已经在该通道上启动了写入操作,那么此方法的调用将阻塞,直到第一个操作完成。
write
中的
GatheringByteChannel
srcs
- 要检索字节的缓冲区
offset
- 要从中检索字节的第一个缓冲区的缓冲区数组中的偏移量;
必须是非负数,不得大于srcs.length
length
- 要访问的缓冲区的最大数量;
必须是非负数,不得大于srcs.length - offset
NotYetConnectedException
- 如果此频道尚未连接
ClosedChannelException
- 如果此通道关闭
AsynchronousCloseException
- 如果另一个线程在写操作正在进行时关闭此通道
ClosedByInterruptException
- 如果另一个线程在写操作正在进行时中断当前线程,从而关闭通道并设置当前线程的中断状态
IOException
- 如果发生其他I / O错误
public final long write(ByteBuffer[] srcs) throws IOException
GatheringByteChannel
复制
调用此方法的形式为c.write(srcs)的行为方式与调用完全相同
c.write(srcs, 0, srcs.length);
write
在接口
GatheringByteChannel
srcs
- 要检索字节的缓冲区
NotYetConnectedException
- 如果此频道尚未连接
ClosedChannelException
- 如果此通道关闭
AsynchronousCloseException
- 如果另一个线程在写操作正在进行时关闭此通道
ClosedByInterruptException
- 如果另一个线程在写操作正在进行时中断当前线程,从而关闭通道并设置当前线程的中断状态
IOException
- 如果发生其他I / O错误
public abstract SocketAddress getLocalAddress() throws IOException
通道为Internet协议套接字地址的bound
,则此方法的返回值为InetSocketAddress
。
如果有一个安全管理器集,它的checkConnect
方法被调用本地地址和-1
作为参数来查看是否允许该操作。 如果不允许的操作, SocketAddress
代表loopback
个地址和通道的套接字的本地端口返回。
getLocalAddress
中的
NetworkChannel
SocketAddress
,该套接字绑定到,或
SocketAddress
代表的环回地址,如果安全管理器拒绝,或
null
如果通道的套接字不绑定
ClosedChannelException
- 如果通道关闭
IOException
- 如果发生I / O错误