目录
构造函数,2个open方法,方法validOps,bind,setOption,shutdownInput/Output
方法socket,isConnected,isConnectionPending,connect,finishConnect,getRemoteAddress
方法3个read,3个write,getLocalAddress
简介
package java.nio.channels;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketOption;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
/**
* 面向流的连接套接字的可选通道。
*
* <p> 套接字通道是通过调用该类的open方法之一来创建的。
* 为任意预先存在的套接字创建通道是不可能的。新创建的套接字通道已打开,但尚未连接。
* 尝试在未连接的通道上调用I/O操作将导致抛出NotYetConnectedException。
* 可以通过调用其connect方法来连接套接字通道;
* 一旦连接,套接字通道将保持连接,直到关闭。
* 套接字通道是否连接可以通过调用它的isConnected方法来确定。
*
* <p> 套接字通道支持非阻塞连接:
* 可以创建一个套接字通道,
* 建立远程套接字链接的过程可以通过connect方法发起,稍后由finishConnect方法完成。
* 连接操作是否正在进行可以通过调用isConnectionPending方法来确定。
*
* <p> 套接字通道支持异步关闭,这类似于Channel类中指定的异步关闭操作。
* 如果一个线程关闭了套接字的输入端,而另一个线程在套接字的通道上阻塞了读操作,
* 那么阻塞线程中的read操作将在不读取任何字节的情况下完成,并返回-1。
* 如果套接字的输出端被一个线程关闭,而另一个线程在套接字的通道上的写操作中被阻塞,
* 那么被阻塞的线程将收到一个AsynchronousCloseException。
*
* <p> 套接字选项使用setOption方法进行配置。套接字通道支持以下选项:
* <blockquote>
* <table border summary="Socket options">
* <tr>
* <th>Option Name</th>
* <th>Description</th>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td>
* <td> 发送缓冲区的大小 </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
* <td> 接收缓冲区的大小 </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE} </td>
* <td> 保持连接处于连接状态 </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
* <td> 重用地址 </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOptions#SO_LINGER SO_LINGER} </td>
* <td> 在关闭时,如果数据存在(当配置为阻塞模式时) </td>
* </tr>
* <tr>
* <td> {@link java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY} </td>
* <td> 禁用Nagle算法 </td>
* </tr>
* </table>
* </blockquote>
* 还可能支持其他(特定于实现的)选项。
*
* <p> 套接字通道对于多个并发线程来说是安全的。
* 它们支持并发读写,尽管在任何给定的时间内最多有一个线程在读,最多有一个线程在写。
* connect和finishConnect方法是相互同步的,当其中一个方法的调用正在进行时,尝试发起读写操作将会阻塞,直到调用完成。</p>
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class SocketChannel
extends AbstractSelectableChannel
implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel
构造函数,2个open方法,方法validOps,bind,setOption,shutdownInput/Output
/**
* 创建实例
*
* @param provider
* The provider that created this channel
*/
protected SocketChannel(SelectorProvider provider) {
super(provider);
}
/**
* 打开套接字通道。
*
* <p> 新通道是通过调用系统范围默认java.nio.channels.spi的SelectorProvider对象的openSocketChannel方法创建的。</p>
*
* @return A new socket channel
*
* @throws IOException
* If an I/O error occurs
*/
public static SocketChannel open() throws IOException {
return SelectorProvider.provider().openSocketChannel();
}
/**
* 打开一个套接字通道并将其连接到一个远程地址。
*
* <p> 这个方便的方法工作起来就像调用open()方法,在产生的套接字通道上调用connect方法,将其远程传递,然后返回该通道。 </p>
*
* @param remote
* The remote address to which the new channel is to be connected
*
* @return A new, and connected, socket channel
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the connect operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the connect operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws UnresolvedAddressException
* If the given remote address is not fully resolved
*
* @throws UnsupportedAddressTypeException
* If the type of the given remote address is not supported
*
* @throws SecurityException
* If a security manager has been installed
* and it does not permit access to the given remote endpoint
*
* @throws IOException
* If some other I/O error occurs
*/
public static SocketChannel open(SocketAddress remote)
throws IOException
{
SocketChannel sc = open();
try {
sc.connect(remote);
} catch (Throwable x) {
try {
sc.close();
} catch (Throwable suppressed) {
x.addSuppressed(suppressed);
}
throw x;
}
assert sc.isConnected();
return sc;
}
/**
* 返回一个操作集,标识此通道支持的操作。
*
* <p> 套接字通道支持连接、读取和写入,
* 因此该方法返回(SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE)。</p>
*
* @return The valid-operation set
*/
public final int validOps() {
return (SelectionKey.OP_READ
| SelectionKey.OP_WRITE
| SelectionKey.OP_CONNECT);
}
// -- Socket-specific operations --
/**
* @throws ConnectionPendingException
* If a non-blocking connect operation is already in progress on
* this channel
* @throws AlreadyBoundException {@inheritDoc}
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
* @throws SecurityException
* If a security manager has been installed and its
* {@link SecurityManager#checkListen checkListen} method denies
* the operation
*
* @since 1.7
*/
@Override
public abstract SocketChannel bind(SocketAddress local)
throws IOException;
/**
* @throws UnsupportedOperationException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*
* @since 1.7
*/
@Override
public abstract <T> SocketChannel setOption(SocketOption<T> name, T value)
throws IOException;
/**
* 在不关闭通道的情况下关闭读取连接。
*
* <p> 一旦停止读取,则在通道上进一步读取将返回-1,即流结束指示。
* 如果连接的输入端已经关闭,则调用此方法没有效果。
*
* @return The channel
*
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
*
* @since 1.7
*/
public abstract SocketChannel shutdownInput() throws IOException;
/**
* 在不关闭通道的情况下关闭写入连接。
*
* <p> 一旦因为写入而关闭,那么进一步尝试写入通道将抛出ClosedChannelException。
* 如果连接的输出端已经关闭,那么调用这个方法没有效果。
*
* @return The channel
*
* @throws NotYetConnectedException
* If this channel is not yet connected
* @throws ClosedChannelException
* If this channel is closed
* @throws IOException
* If some other I/O error occurs
*
* @since 1.7
*/
public abstract SocketChannel shutdownOutput() throws IOException;
方法socket,isConnected,isConnectionPending,connect,finishConnect,getRemoteAddress
/**
* 检索与此通道关联的套接字。
*
* <p> 返回的对象不会声明没有在java.net.Socket类中声明的任何公共方法。 </p>
*
* @return A socket associated with this channel
*/
public abstract Socket socket();
/**
* 判断此通道的网络套接字是否已连接。
*
* @return <tt>true</tt> if, and only if, this channel's network socket
* is {@link #isOpen open} and connected
*/
public abstract boolean isConnected();
/**
* 说明该通道上是否有正在进行的连接操作。
*
* @return <tt>true</tt> if, and only if, a connection operation has been
* initiated on this channel but not yet completed by invoking the
* {@link #finishConnect finishConnect} method
*/
public abstract boolean isConnectionPending();
/**
* 连接此通道的套接字。
*
* <p> 如果此通道处于非阻塞模式,则此方法的调用将启动非阻塞连接操作。
* 如果连接立即建立,就像本地连接一样,那么这个方法将返回true。
* 否则,该方法将返回false,并且连接操作必须在稍后通过调用finishConnect方法来完成。
*
* <p> 如果此通道处于阻塞模式,则此方法的调用将阻塞,直到建立连接或发生I/O错误。
*
* <p> 此方法执行与java.net.Socket类完全相同的安全检查。
* 也就是说,如果已经安装了安全管理器,那么该方法将验证其checkConnect方法是否允许连接到给定远程端点的地址和端口号。
*
* <p> 这个方法可以在任何时候被调用。如果在此通道上的读或写操作被调用时,
* 该方法的调用正在进行中,那么该操作将首先阻塞,直到该调用完成。
* 如果发起连接尝试但失败,也就是说,如果此方法的调用抛出一个检查过的异常,则通道将被关闭。</p>
*
* @param remote
* The remote address to which this channel is to be connected
*
* @return <tt>true</tt> if a connection was established,
* <tt>false</tt> if this channel is in non-blocking mode
* and the connection operation is in progress
*
* @throws AlreadyConnectedException
* If this channel is already connected
*
* @throws ConnectionPendingException
* If a non-blocking connection operation is already in progress
* on this channel
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the connect operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the connect operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws UnresolvedAddressException
* If the given remote address is not fully resolved
*
* @throws UnsupportedAddressTypeException
* If the type of the given remote address is not supported
*
* @throws SecurityException
* If a security manager has been installed
* and it does not permit access to the given remote endpoint
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract boolean connect(SocketAddress remote) throws IOException;
/**
* 完成连接socket通道的过程。
*
* <p> 通过将socket通道置于非阻塞模式,然后调用其connect方法,可以启动非阻塞连接操作。
* 一旦建立了连接,或者尝试失败,套接字通道将变为可连接的,并且可能会调用此方法来完成连接序列。
* 如果connection操作失败,则调用此方法将要抛出适当的java.io.IOException。
*
* <p> 如果此通道已经连接,则此方法不会阻塞,并将立即返回true。
* 如果这个通道是非阻塞模式,那么如果连接过程还没有完成,这个方法将返回false。
* 如果此通道处于blocking模式,则此方法将阻塞,
* 直到连接完成或失败,并总是返回true或抛出描述失败的checked exception。
*
* <p> 这个方法可以在任何时候被调用。如果在此通道上的读或写操作被调用时,
* 该方法的调用正在进行中,那么该操作将首先阻塞,直到该调用完成。
* 如果连接尝试失败,也就是说,如果这个方法的调用抛出一个检查过的异常,那么通道将被关闭。</p>
*
* @return <tt>true</tt> if, and only if, this channel's socket is now
* connected
*
* @throws NoConnectionPendingException
* If this channel is not connected and a connection operation
* has not been initiated
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the connect operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the connect operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract boolean finishConnect() throws IOException;
/**
* 返回此通道套接字连接到的远程地址。
*
* <p> 如果通道被绑定并连接到Internet Protocol 套接字地址,那么该方法的返回值类型为java.net.InetSocketAddress。
*
* @return The remote address; {@code null} if the channel's socket is not
* connected
*
* @throws ClosedChannelException
* If the channel is closed
* @throws IOException
* If an I/O error occurs
*
* @since 1.7
*/
public abstract SocketAddress getRemoteAddress() throws IOException;
方法3个read,3个write,getLocalAddress
// -- ByteChannel operations --
/**
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
public abstract int read(ByteBuffer dst) throws IOException;
/**
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
public abstract long read(ByteBuffer[] dsts, int offset, int length)
throws IOException;
/**
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
public final long read(ByteBuffer[] dsts) throws IOException {
return read(dsts, 0, dsts.length);
}
/**
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
public abstract int write(ByteBuffer src) throws IOException;
/**
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
public abstract long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
/**
* @throws NotYetConnectedException
* If this channel is not yet connected
*/
public final long write(ByteBuffer[] srcs) throws IOException {
return write(srcs, 0, srcs.length);
}
/**
* {@inheritDoc}
* <p>
* 如果设置了安全管理器,则使用本地地址和-1作为参数调用其checkConnect方法,以查看是否允许该操作。
* 如果不允许该操作,则返回一个表示环回地址和通道套接字的本地端口的SocketAddress。
*
* @return The {@code SocketAddress} that the socket is bound to, or the
* {@code SocketAddress} representing the loopback address if
* denied by the security manager, or {@code null} if the
* channel's socket is not bound
*
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
*/
@Override
public abstract SocketAddress getLocalAddress() throws IOException;