ServerSocketChannel的类结构图:
上文说了多路复用器Selector,这篇文章来解读ServerSocketChannel类,首先看创建ServerSocketChannel类的open方法,
public static ServerSocketChannel open() throws IOException {
return SelectorProvider.provider().openServerSocketChannel();
}
他也是调用的SelectorProvider.provider()拿到的provider对象创建的ServerSocketChannel,上文的Selector、Pipe都是通过这一个provider对象创建的,对于windows操作系统来说他的实现类就是WindowsSelectorProvider,而WindowsSelectorProvider类中只是实现了openSelector方法,openServerSocketChannel方法也和openPipe方法一样由父类SelectorProviderImpl来实现的,接着看他的openServerSocketChannel方法:
public ServerSocketChannel openServerSocketChannel() throws IOException {
return new ServerSocketChannelImpl(this);
}
同样也就是创建了一个ServerSocketChannelImpl对象,下面看看这个对象的构造方法:
ServerSocketChannelImpl(SelectorProvider sp) throws IOException {
super(sp);
this.fd = Net.serverSocket(true);
this.fdVal = IOUtil.fdVal(fd);
this.state = ST_INUSE;
}
首先也是调用父类的构造方法将SelectorProvider这个对象初始化到父类的父类AbstractSelectableChannel中的,接着创建了一个文件描述符对象设置为成员属性,注意这里传入的参数是true,代表创建的ServerSocketChannel对应的文件描述符对象是阻塞的,接下来设置fdVal值,保存的是内核中文件当前文件描述符对象的index,接着设置一个ServerSocketChannel的状态。
// fd value needed for dev/poll. This value will remain valid
// even after the value in the file descriptor object has been set to -1
private int fdVal;
接着看看servChannel.configureBlocking(false);方法:
public final SelectableChannel configureBlocking(boolean block)
throws IOException
{
synchronized (regLock) {
if (!isOpen())
throw new ClosedChannelException();
if (blocking == block)
return this;
if (block && haveValidKeys())
throw new IllegalBlockingModeException();
implConfigureBlocking(block);
blocking = block;
}
return this;
}
protected void implConfigureBlocking(boolean block) throws IOException {
IOUtil.configureBlocking(fd, block);
}
调用的是IOUtil.configureBlocking(fd, block);方法将当前ServerSocketChannel设置为非阻塞的模式(前面说过初始化创建的是阻塞的)
接下来看看ServerSocketChannel是如何绑定IP的port的,代码如下:
servChannel.socket().bind(new InetSocketAddress(port), 1024);
首先看下ServerSocketChannelImpl的socket()方法
public ServerSocket socket() {
synchronized (stateLock) {
if (socket == null)